Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
librarydialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  librarydialog.cpp
3  -------------------
4  begin : Sun Jun 04 2006
5  copyright : (C) 2006 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 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <QtGui>
22 #include <QLabel>
23 #include <QLineEdit>
24 #include <QTextEdit>
25 #include <QTextStream>
26 
27 #include <QDataStream>
28 #include <QCheckBox>
29 #include <QTreeWidgetItem>
30 #include <QValidator>
31 #include <QMessageBox>
32 #include <QPushButton>
33 #include <QScrollArea>
34 #include <QButtonGroup>
35 #include <QVBoxLayout>
36 #include <QHBoxLayout>
37 #include <QStackedWidget>
38 #include <QDebug>
39 
40 #include "librarydialog.h"
41 #include "qucs.h"
42 #include "main.h"
43 #include "schematic.h"
44 
45 extern SubMap FileList;
46 
47 LibraryDialog::LibraryDialog(QucsApp *App_, QTreeWidgetItem *SchematicList)
48  : QDialog(App_)
49 {
50  App = App_;
51  setWindowTitle(tr("Create Library"));
52 
53  Expr.setPattern("[\\w_]+");
54  Validator = new QRegExpValidator(Expr, this);
55 
56  curDescr = 0; // description counter, prev, next
57 
58  // ...........................................................
59  all = new QVBoxLayout(this);
60  all->setMargin(5);
61  all->setSpacing(6);
62 
63  stackedWidgets = new QStackedWidget(this);
64  all->addWidget(stackedWidgets);
65 
66 
67  // stacked 0 - select subcirbuit, name, and descriptions
68  // ...........................................................
69  QWidget *selectSubckt = new QWidget();
70  stackedWidgets->addWidget(selectSubckt);
71 
72  QVBoxLayout *selectSubcktLayout = new QVBoxLayout();
73  selectSubckt->setLayout(selectSubcktLayout);
74 
75 
76  QHBoxLayout *h1 = new QHBoxLayout();
77  selectSubcktLayout->addLayout(h1);
78  theLabel = new QLabel(tr("Library Name:"));
79  h1->addWidget(theLabel);
80  NameEdit = new QLineEdit();
81  h1->addWidget(NameEdit);
82  NameEdit->setValidator(Validator);
83 
84  // ...........................................................
85  Group = new QGroupBox(tr("Choose subcircuits:"));
86  selectSubcktLayout->addWidget(Group);
87 
88  QScrollArea *scrollArea = new QScrollArea(Group);
89  scrollArea->setWidgetResizable(true);
90 
91  QWidget *scrollWidget = new QWidget();
92 
93  QVBoxLayout *checkBoxLayout = new QVBoxLayout();
94  scrollWidget->setLayout(checkBoxLayout);
95  scrollArea->setWidget(scrollWidget);
96 
97  QVBoxLayout *areaLayout = new QVBoxLayout();
98  areaLayout->addWidget(scrollArea);
99  Group->setLayout(areaLayout);
100 
101  // ...........................................................
102  QHBoxLayout *hCheck = new QHBoxLayout();
103  selectSubcktLayout->addLayout(hCheck);
104  checkDescr = new QCheckBox(tr("Add subcircuit description"));
105  checkDescr->setChecked(true);
106  hCheck->addWidget(checkDescr);
107  hCheck->addStretch();
108  connect(checkDescr, SIGNAL(stateChanged(int)), this, SLOT(slotCheckDescrChanged(int)));
109 
110  // ...........................................................
111  QGridLayout *gridButts = new QGridLayout();
112  selectSubcktLayout->addLayout(gridButts);
113  ButtSelectAll = new QPushButton(tr("Select All"));
114  gridButts->addWidget(ButtSelectAll, 0, 0);
115  connect(ButtSelectAll, SIGNAL(clicked()), SLOT(slotSelectAll()));
116  ButtSelectNone = new QPushButton(tr("Deselect All"));
117  gridButts->addWidget(ButtSelectNone, 0, 1);
118  connect(ButtSelectNone, SIGNAL(clicked()), SLOT(slotSelectNone()));
119  // ...........................................................
120  ButtCancel = new QPushButton(tr("Cancel"));
121  gridButts->addWidget(ButtCancel, 1, 0);
122  connect(ButtCancel, SIGNAL(clicked()), SLOT(reject()));
123  ButtCreateNext = new QPushButton(tr("Next >>"));
124  gridButts->addWidget(ButtCreateNext, 1, 1);
125  connect(ButtCreateNext, SIGNAL(clicked()), SLOT(slotCreateNext()));
126  ButtCreateNext->setDefault(true);
127 
128 
129  // stacked 1 - enter description, loop over checked subckts
130  // ...........................................................
131  QWidget *subcktDescr = new QWidget();
132  stackedWidgets->addWidget(subcktDescr);
133 
134  QVBoxLayout *subcktDescrLayout = new QVBoxLayout();
135  subcktDescr->setLayout(subcktDescrLayout);
136 
137  QHBoxLayout *hbox = new QHBoxLayout();
138  subcktDescrLayout->addLayout(hbox);
139  QLabel *libName = new QLabel(tr("Enter description for:"));
140  hbox->addWidget(libName);
141  checkedCktName = new QLabel();
142  checkedCktName->setText("dummy");
143  hbox->addWidget(checkedCktName);
144 
145  QGroupBox *descrBox = new QGroupBox(tr("Description:"));
146  subcktDescrLayout->addWidget(descrBox);
147  textDescr = new QTextEdit();
148  textDescr->setTextFormat(Qt::PlainText);
149  textDescr->setWordWrapMode(QTextOption::NoWrap);
150  connect(textDescr, SIGNAL(textChanged()), SLOT(slotUpdateDescription()));
151  QVBoxLayout *vGroup = new QVBoxLayout;
152  vGroup->addWidget(textDescr);
153  descrBox->setLayout(vGroup);
154 
155  // ...........................................................
156  gridButts = new QGridLayout();
157  subcktDescrLayout->addLayout(gridButts);
158  prevButt = new QPushButton(tr("Previous"));
159  gridButts->addWidget(prevButt, 0, 0);
160  prevButt->setDisabled(true);
161  connect(prevButt, SIGNAL(clicked()), SLOT(slotPrevDescr()));
162  nextButt = new QPushButton(tr("Next >>"));
163  nextButt->setDefault(true);
164  gridButts->addWidget(nextButt, 0, 1);
165  connect(nextButt, SIGNAL(clicked()), SLOT(slotNextDescr()));
166  // ...........................................................
167  ButtCancel = new QPushButton(tr("Cancel"));
168  gridButts->addWidget(ButtCancel, 1, 0);
169  connect(ButtCancel, SIGNAL(clicked()), SLOT(reject()));
170  createButt = new QPushButton(tr("Create"));
171  connect(createButt, SIGNAL(clicked()), SLOT(slotSave()));
172  gridButts->addWidget(createButt, 1, 1);
173  createButt->setDisabled(true);
174 
175 
176  // stacked 2 - show error / sucess message
177  // ...........................................................
178  QWidget *msg = new QWidget();
179  stackedWidgets->addWidget(msg);
180 
181  QVBoxLayout *msgLayout = new QVBoxLayout();
182  msg->setLayout(msgLayout);
183 
184  QHBoxLayout *hbox1 = new QHBoxLayout();
185  msgLayout->addLayout(hbox1);
186  QLabel *finalLabel = new QLabel(tr("Library Name:"));
187  hbox1->addWidget(finalLabel);
188  libSaveName = new QLabel();
189  hbox1->addWidget(libSaveName);
190 
191  QGroupBox *msgBox = new QGroupBox(tr("Message:"));
192  msgLayout->addWidget(msgBox);
193  ErrText = new QTextEdit();
194  ErrText->setTextFormat(Qt::PlainText);
195  ErrText->setWordWrapMode(QTextOption::NoWrap);
196  ErrText->setReadOnly(true);
197  QVBoxLayout *vbox1 = new QVBoxLayout();
198  vbox1->addWidget(ErrText);
199  msgBox->setLayout(vbox1);
200 
201  QHBoxLayout *hbox2 = new QHBoxLayout();
202  hbox2->addStretch();
203  QPushButton *close = new QPushButton(tr("Close"));
204  hbox2->addWidget(close);
205  connect(close, SIGNAL(clicked()), SLOT(reject()));
206  msgLayout->addLayout(hbox2);
207 
208  // ...........................................................
209  // insert all subcircuits of into checklist
210  QTreeWidgetItem *p ;
211  for(int i=0; i < SchematicList->childCount(); i++){
212  p = SchematicList->child(i);
213  if(p->parent() == 0)
214  break;
215  if(!p->text(1).isEmpty()){
216  QCheckBox *subCheck = new QCheckBox(p->text(0));
217  checkBoxLayout->addWidget(subCheck);
218  BoxList.append(subCheck);
219  }
220  }
221 
222  if(BoxList.isEmpty()) {
223  ButtCreateNext->setEnabled(false);
224  QLabel *noProj = new QLabel(tr("No projects!"));
225  checkBoxLayout->addWidget(noProj);
226  }
227 }
228 
229 
231 {
232  delete all;
233  delete Validator;
234 }
235 
236 // ---------------------------------------------------------------
238 {
239  if(NameEdit->text().isEmpty()) {
240  QMessageBox::critical(this, tr("Error"), tr("Please insert a library name!"));
241  return;
242  }
243 
244  int count=0;
245  QCheckBox *p;
246  QListIterator<QCheckBox *> i(BoxList);
247  while(i.hasNext()){
248  p = i.next();
249  if(p->isChecked()) {
250  SelectedNames.append(p->text());
251  Descriptions.append("");
252  count++;
253  }
254  }
255 
256  if(count < 1) {
257  QMessageBox::critical(this, tr("Error"), tr("Please choose at least one subcircuit!"));
258  return;
259  }
260 
262  if(!LibDir.cd("user_lib")) { // user library directory exists ?
263  if(!LibDir.mkdir("user_lib")) { // no, then create it
264  QMessageBox::warning(this, tr("Warning"),
265  tr("Cannot create user library directory !"));
266  return;
267  }
268  LibDir.cd("user_lib");
269  }
270 
271  LibFile.setName(QucsSettings.LibDir + NameEdit->text() + ".lib");
272  if(LibFile.exists()) {
273  QMessageBox::critical(this, tr("Error"), tr("A system library with this name already exists!"));
274  return;
275  }
276 
277  LibFile.setName(LibDir.absFilePath(NameEdit->text()) + ".lib");
278  if(LibFile.exists()) {
279  QMessageBox::critical(this, tr("Error"), tr("A library with this name already exists!"));
280  return;
281  }
282 
283  if (checkDescr->checkState() == Qt::Checked){
284  // user enter descriptions
285  stackedWidgets->setCurrentIndex(1); // subcircuit description view
286 
287  checkedCktName->setText(SelectedNames[0]);
288  textDescr->setText(Descriptions[0]);
289 
290  if (SelectedNames.count() == 1){
291  prevButt->setDisabled(true);
292  nextButt->setDisabled(true);
293  createButt->setEnabled(true);
294  }
295  }
296  else {
297  // save whitout description
298  emit slotSave();
299  }
300 }
301 
302 // ---------------------------------------------------------------
303 void LibraryDialog::intoStream(QTextStream &Stream, QString &tmp,
304  const char *sec)
305 {
306  int i = tmp.find("TOP LEVEL MARK");
307  if(i >= 0) {
308  i = tmp.find('\n',i) + 1;
309  tmp = tmp.mid(i);
310  }
311  Stream << " <" << sec << ">";
312  Stream << tmp;
313  Stream << " </" << sec << ">\n";
314 }
315 
316 // ---------------------------------------------------------------
317 int LibraryDialog::intoFile(QString &ifn, QString &ofn, QStringList &IFiles)
318 {
319  int error = 0;
320  QFile ifile(ifn);
321  if(!ifile.open(QIODevice::ReadOnly)) {
322  ErrText->insert(QObject::tr("ERROR: Cannot open file \"%1\".\n").
323  arg(ifn));
324  error++;
325  }
326  else {
327  QByteArray FileContent = ifile.readAll();
328  ifile.close();
329  if(ifile.name().right(4) == ".lst")
330  LibDir.remove(ifile.name());
331  QDir LibDirSub(LibDir);
332  if(!LibDirSub.cd(NameEdit->text())) {
333  if(!LibDirSub.mkdir(NameEdit->text())) {
334  ErrText->insert(
335  QObject::tr("ERROR: Cannot create user library subdirectory !\n"));
336  error++;
337  }
338  LibDirSub.cd(NameEdit->text());
339  }
340  QFileInfo Info(ofn);
341  ofn = Info.fileName();
342  IFiles.append(ofn);
343  QFile ofile;
344  ofile.setName(LibDirSub.absFilePath(ofn));
345  if(!ofile.open(QIODevice::WriteOnly)) {
346  ErrText->insert(
347  QObject::tr("ERROR: Cannot create file \"%1\".\n").arg(ofn));
348  error++;
349  }
350  else {
351  QDataStream ds(&ofile);
352  ds.writeRawBytes(FileContent.data(), FileContent.size());
353  ofile.close();
354  }
355  }
356  return error;
357 }
358 
359 // ---------------------------------------------------------------
361 {
362  if (state == Qt::Unchecked){
363  ButtCreateNext->setText(tr("Create"));
364  }
365  else {
366  ButtCreateNext->setText(tr("Next..."));
367  }
368 }
369 
370 // ---------------------------------------------------------------
372 {
373  if ( curDescr > 0 ) {
374  nextButt->setDisabled(false);
376  curDescr--;
377  checkedCktName->setText(SelectedNames[curDescr]);
378  textDescr->setText(Descriptions[curDescr]);
379  }
380 
381  if (curDescr == 0){
382  prevButt->setDisabled(true);
383  nextButt->setEnabled(true);
384  }
385 }
386 
387 // ---------------------------------------------------------------
389 {
390  if ( curDescr < SelectedNames.count()) {
391  prevButt->setDisabled(false);
393  curDescr++;
394  checkedCktName->setText(SelectedNames[curDescr]);
395  textDescr->setText(Descriptions[curDescr]);
396  }
397 
398  if (curDescr == SelectedNames.count()-1){
399  nextButt->setDisabled(true);
400  createButt->setEnabled(true);
401  }
402 }
403 
405 {
406  // store on every change
407  Descriptions[curDescr] = textDescr->text();
408 }
409 
410 // ---------------------------------------------------------------
412 {
413  stackedWidgets->setCurrentIndex(2); //message window
414  libSaveName->setText(NameEdit->text() + ".lib");
415 
416  ErrText->insert(tr("Saving library..."));
417 
418  if(!LibFile.open(QIODevice::WriteOnly)) {
419  ErrText->append(tr("Error: Cannot create library!"));
420  return;
421  }
422  QTextStream Stream;
423  Stream.setDevice(&LibFile);
424  Stream << "<Qucs Library " PACKAGE_VERSION " \""
425  << NameEdit->text() << "\">\n\n";
426 
427  bool Success = true, ret;
428 
429  QString tmp;
430  QTextStream ts(&tmp, QIODevice::WriteOnly);
431 
432  for (int i=0; i < SelectedNames.count(); i++) {
433  ErrText->insert("\n=================\n");
434 
435  QString description = "";
436  if(checkDescr->checkState() == Qt::Checked)
437  description = Descriptions[i];
438 
439  Stream << "<Component " + SelectedNames[i].section('.',0,0) + ">\n"
440  << " <Description>\n"
441  << description
442  << "\n </Description>\n";
443 
444  Schematic *Doc = new Schematic(0, QucsSettings.QucsWorkDir.filePath(SelectedNames[i]));
445  ErrText->insert(tr("Loading subcircuit \"%1\".\n").arg(SelectedNames[i]));
446  if(!Doc->loadDocument()) { // load document if possible
447  delete Doc;
448  ErrText->append(tr("Error: Cannot load subcircuit \"%1\".").
449  arg(SelectedNames[i]));
450  break;
451  }
452  Doc->DocName = NameEdit->text() + "_" + SelectedNames[i];
453  Success = false;
454 
455  // save analog model
456  tmp.truncate(0);
457  Doc->isAnalog = true;
458 
459  ErrText->insert("\n");
460  ErrText->insert(tr("Creating Qucs netlist.\n"));
461  ret = Doc->createLibNetlist(&ts, ErrText, -1);
462  if(ret) {
463  intoStream(Stream, tmp, "Model");
464  int error = 0;
465  QStringList IFiles;
466  SubMap::Iterator it = FileList.begin();
467  while(it != FileList.end()) {
468  QString f = it.data().File;
469  QString ifn, ofn;
470  if(it.data().Type == "SCH") {
471  ifn = f + ".lst";
472  ofn = ifn;
473  }
474  else if(it.data().Type == "CIR") {
475  ifn = f + ".lst";
476  ofn = ifn;
477  }
478  if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles);
479  it++;
480  }
481  FileList.clear();
482  if(!IFiles.isEmpty()) {
483  Stream << " <ModelIncludes \"" << IFiles.join("\" \"") << "\">\n";
484  }
485  Success = error > 0 ? false : true;
486  }
487  else {
488  ErrText->insert("\n");
489  ErrText->insert(tr("Error: Cannot create netlist for \"%1\".\n").arg(SelectedNames[i]));
490  }
491 
492  // save verilog model
493  tmp.truncate(0);
494  Doc->isVerilog = true;
495  Doc->isAnalog = false;
496 
497  ErrText->insert("\n");
498  ErrText->insert(tr("Creating Verilog netlist.\n"));
499  ret = Doc->createLibNetlist(&ts, ErrText, 0);
500  if(ret) {
501  intoStream(Stream, tmp, "VerilogModel");
502  int error = 0;
503  QStringList IFiles;
504  SubMap::Iterator it = FileList.begin();
505  while(it != FileList.end()) {
506  QString f = it.data().File;
507  QString ifn, ofn;
508  if(it.data().Type == "SCH") {
509  ifn = f + ".lst";
510  ofn = f + ".v";
511  }
512  else if(it.data().Type == "VER") {
513  ifn = f;
514  ofn = ifn;
515  }
516  if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles);
517  it++;
518  }
519  FileList.clear();
520  if(!IFiles.isEmpty()) {
521  Stream << " <VerilogModelIncludes \""
522  << IFiles.join("\" \"") << "\">\n";
523  }
524  Success = error > 0 ? false : true;
525  }
526  else {
527  ErrText->insert("\n");
528  }
529 
530  // save vhdl model
531  tmp.truncate(0);
532  Doc->isVerilog = false;
533  Doc->isAnalog = false;
534 
535  ErrText->insert(tr("Creating VHDL netlist.\n"));
536  ret = Doc->createLibNetlist(&ts, ErrText, 0);
537  if(ret) {
538  intoStream(Stream, tmp, "VHDLModel");
539  int error = 0;
540  QStringList IFiles;
541  SubMap::Iterator it = FileList.begin();
542  while(it != FileList.end()) {
543  QString f = it.data().File;
544  QString ifn, ofn;
545  if(it.data().Type == "SCH") {
546  ifn = f + ".lst";
547  ofn = f + ".vhdl";
548  }
549  else if(it.data().Type == "VHD") {
550  ifn = f;
551  ofn = ifn;
552  }
553  if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles);
554  it++;
555  }
556  FileList.clear();
557  if(!IFiles.isEmpty()) {
558  Stream << " <VHDLModelIncludes \""
559  << IFiles.join("\" \"") << "\">\n";
560  }
561  Success = error > 0 ? false : true;
562  }
563  else {
564  ErrText->insert("\n");
565  }
566 
567  Stream << " <Symbol>\n";
568  Doc->createSubcircuitSymbol();
569  Painting *pp;
570  for(pp = Doc->SymbolPaints.first(); pp != 0; pp = Doc->SymbolPaints.next())
571  Stream << " <" << pp->save() << ">\n";
572 
573  Stream << " </Symbol>\n"
574  << "</Component>\n\n";
575 
576  delete Doc;
577 
578  if(!Success) break;
579 
580  } // for
581 
582  LibFile.close();
583  if(!Success) {
584  LibFile.remove();
585  ErrText->append(tr("Error creating library."));
586  return;
587  }
588 
589  ErrText->append(tr("Successfully created library."));
590 }
591 
592 // ---------------------------------------------------------------
594 {
595  QCheckBox *p;
596  QListIterator<QCheckBox *> i(BoxList);
597  while(i.hasNext()){
598  p = i.next();
599  p->setChecked(true);
600  }
601 }
602 
603 // ---------------------------------------------------------------
605 {
606  QCheckBox *p;
607  QListIterator<QCheckBox *> i(BoxList);
608  while(i.hasNext()){
609  p = i.next();
610  p->setChecked(false);
611  }
612 }
QTextEdit * textDescr
Definition: librarydialog.h:75
QGroupBox * Group
Definition: librarydialog.h:76
QDir QucsWorkDir
Definition: main.h:65
QStringList SelectedNames
Definition: librarydialog.h:81
tQucsSettings QucsSettings
Definition: main.cpp:52
virtual QString save()
Definition: painting.cpp:39
QucsApp * App
Definition: librarydialog.h:85
QPushButton * ButtSelectNone
Definition: librarydialog.h:77
QPushButton * prevButt
Definition: librarydialog.h:78
bool isVerilog
Definition: schematic.h:297
QMap< QString, SubFile > SubMap
Definition: schematic.h:67
int intoFile(QString &, QString &, QStringList &)
QTextEdit * ErrText
Definition: librarydialog.h:74
bool createSubcircuitSymbol()
Definition: schematic.cpp:158
QLabel * theLabel
Definition: librarydialog.h:70
Definitions and declarations for the main application.
QStackedWidget * stackedWidgets
Definition: librarydialog.h:69
QLineEdit * NameEdit
Definition: librarydialog.h:73
QPushButton * ButtCancel
Definition: librarydialog.h:77
QPushButton * nextButt
Definition: librarydialog.h:78
QPushButton * ButtSelectAll
Definition: librarydialog.h:77
QCheckBox * checkDescr
Definition: librarydialog.h:83
QPushButton * ButtCreateNext
Definition: librarydialog.h:77
bool isAnalog
Definition: schematic.h:296
QRegExpValidator * Validator
Definition: librarydialog.h:89
QPushButton * createButt
Definition: librarydialog.h:79
SubMap FileList
void slotCheckDescrChanged(int)
QDir QucsHomeDir
Definition: main.h:66
bool createLibNetlist(QTextStream *, QTextEdit *, int)
Q3PtrList< Painting > SymbolPaints
Definition: schematic.h:125
LibraryDialog(QucsApp *, QTreeWidgetItem *)
QString DocName
Definition: qucsdoc.h:51
QLabel * checkedCktName
Definition: librarydialog.h:71
QList< QCheckBox * > BoxList
Definition: librarydialog.h:80
Definition: qucs.h:61
void intoStream(QTextStream &, QString &, const char *)
QLabel * libSaveName
Definition: librarydialog.h:72
QStringList Descriptions
Definition: librarydialog.h:82
QVBoxLayout * all
Definition: librarydialog.h:68
bool loadDocument()
void slotUpdateDescription()
QString LibDir
Definition: main.h:59