Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
qucs.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qucs.cpp
3  ----------
4  begin : Thu Aug 28 2003
5  copyright : (C) 2003, 2004, 2005, 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 <QDebug>
23 #include <QtCore>
24 #include <QtSvg>
25 #include <limits.h>
26 
27 #include <QProcess>
28 #include <Q3SyntaxHighlighter>
29 //Added by qt3to4:
30 #include <Q3PtrList>
31 #include <Q3TextEdit>
32 
33 #include "main.h"
34 #include "qucs.h"
35 #include "qucsdoc.h"
36 #include "textdoc.h"
37 #include "syntax.h"
38 #include "schematic.h"
39 #include "mouseactions.h"
40 #include "messagedock.h"
41 #include "wire.h"
42 #include "module.h"
43 #include "components/components.h"
44 #include "paintings/paintings.h"
45 #include "diagrams/diagrams.h"
46 #include "dialogs/savedialog.h"
47 #include "dialogs/newprojdialog.h"
48 #include "dialogs/settingsdialog.h"
52 #include "dialogs/searchdialog.h"
53 #include "dialogs/sweepdialog.h"
54 #include "dialogs/labeldialog.h"
55 #include "dialogs/matchdialog.h"
56 #include "dialogs/simmessage.h"
57 #include "dialogs/exportdialog.h"
58 //#include "dialogs/vtabwidget.h"
59 //#include "dialogs/vtabbeddockwidget.h"
60 #include "octave_window.h"
61 #include "../qucs-lib/qucslib_common.h"
62 
63 extern const char *empty_xpm[];
64 
65 
66 // IconView without dragging icon bitmap
67 /*
68 class myIconView : public Q3IconView
69 {
70 public:
71  myIconView(QWidget* parent_) : Q3IconView(parent_, 0, 0) {};
72  ~myIconView() {};
73 
74 protected:
75  Q3DragObject *dragObject() {
76  Q3IconViewItem *Item = currentItem();
77  if(!Item) return 0;
78 
79  // no picture during dragging, but bounding rectangles in QListView
80  Q3IconDrag *DragPic = new Q3IconDrag( viewport() );
81  DragPic->setPixmap( QPixmap(empty_xpm), QPoint(0, 0) );
82  DragPic->append( Q3IconDragItem(),
83  QRect( Item->pixmapRect().width() / -2,
84  Item->pixmapRect().height() / -2,
85  Item->pixmapRect().width(), Item->pixmapRect().height() ),
86  QRect( Item->textRect().width() / -2,
87  Item->pixmapRect().height() / 2 + 5,
88  Item->textRect().width(), Item->textRect().height() ) );
89  return DragPic;
90  };
91 };
92 */
93 
94 
96 {
97  setCaption("Qucs " PACKAGE_VERSION);
98 
99  spiceExtensions << "*.sp" << "*.cir" << "*.spc" << "*.spi";
100 
102  tr("Schematic") + " (*.sch);;" +
103  tr("Data Display") + " (*.dpl);;" +
104  tr("Qucs Documents") + " (*.sch *.dpl);;" +
105  tr("VHDL Sources") + " (*.vhdl *.vhd);;" +
106  tr("Verilog Sources") + " (*.v);;" +
107  tr("Verilog-A Sources") + " (*.va);;" +
108  tr("Octave Scripts") + " (*.m *.oct);;" +
109  tr("Spice Files") + getSpiceFileFilter() +
110  tr("Any File")+" (*)";
111  //QucsSettings.QucsWorkDir.setPath(QDir::homeDirPath()+QDir::convertSeparators ("/.qucs"));
112  //QucsSettings.QucsHomeDir.setPath(QDir::homeDirPath()+QDir::convertSeparators ("/.qucs"));
113 
116 
117  move (QucsSettings.x, QucsSettings.y);
118  resize(QucsSettings.dx, QucsSettings.dy);
119 
120  MouseMoveAction = 0;
121  MousePressAction = 0;
122  MouseReleaseAction = 0;
124 
125  initView();
126  initActions();
127  initMenuBar();
128  initToolBar();
129  initStatusBar();
130  viewToolBar->setOn(true);
131  viewStatusBar->setOn(true);
132  viewBrowseDock->setOn(true);
133  slotViewOctaveDock(false);
134  initCursorMenu();
135  HierarchyHistory.setAutoDelete(true);
137 
138  // default settings of the printer
139  Printer = new QPrinter(QPrinter::HighResolution);
140 #if defined (QT_VERSION) && QT_VERSION > 0x030200
141  Printer->setOptionEnabled(QPrinter::PrintSelection, true);
142  Printer->setOptionEnabled(QPrinter::PrintPageRange, false);
143  Printer->setOptionEnabled(QPrinter::PrintToFile, true);
144 #endif
145  Printer->setColorMode(QPrinter::Color);
146  Printer->setFullPage(true);
147 
148  // instance of small text search dialog
149  SearchDia = new SearchDialog(this);
150 
151  // creates a document called "untitled"
152  // it configures itself and get appended to App->DocumentTab
153  new Schematic(this, "");
154 
155  select->setOn(true); // switch on the 'select' action
156  switchSchematicDoc(true); // "untitled" document is schematic
157 
158  lastExportFilename = QDir::homePath() + QDir::separator() + "export.png";
159 
160  // load documents given as command line arguments
161  for(int z=1; z<qApp->argc(); z++) {
162  QString arg = qApp->argv()[z];
163  if(*(arg) != '-') {
164  // allow uri's: file:/home/linuxuser/Desktop/example.sch
165  //TODO
166  //if(arg.contains(":/")) {
167  //QString f = QDir::convertSeparators(Q3UriDrag::uriToLocalFile(arg));
168  // if(f.isEmpty()) f = arg;
169  // gotoPage(f);
170  //} else {
171  // get and set absolute path, QucsWorkDir now finds subcircuits
172  QFileInfo Info(arg);
173  QucsSettings.QucsWorkDir.setPath(Info.absoluteDir().absolutePath());
174  arg = QucsSettings.QucsWorkDir.filePath(Info.fileName());
175  gotoPage(arg);
176  //}
177  }
178  }
179 }
180 
182 {
184  delete Printer;
185 }
186 
187 
188 // #######################################################################
189 // ########## ##########
190 // ########## Creates the working area (QTabWidget etc.) ##########
191 // ########## ##########
192 // #######################################################################
194 {
195 
196  Content->clear();
197 
198  ConOthers = new QTreeWidgetItem(Content);
199  ConOthers->setText(0, tr("Others"));
200  ConDatasets = new QTreeWidgetItem(Content);
201  ConDatasets->setText(0, tr("Datasets"));
202  ConDisplays = new QTreeWidgetItem(Content);
203  ConDisplays->setText(0, tr("Data Displays"));
204  ConOctave = new QTreeWidgetItem(Content);
205  ConOctave->setText(0, tr("Octave"));
206  ConVerilog = new QTreeWidgetItem(Content);
207  ConVerilog->setText(0, tr("Verilog"));
208  ConVerilogA = new QTreeWidgetItem(Content);
209  ConVerilogA->setText(0, tr("Verilog-A"));
210  ConSources = new QTreeWidgetItem(Content);
211  ConSources->setText(0, tr("VHDL"));
212  ConSchematics = new QTreeWidgetItem(Content);
213  ConSchematics->setText(0, tr("Schematics"));
214 
215 }
216 
221 {
222 
223 
224  // set application icon
225  // APPLE sets the QApplication icon with Info.plist
226 #ifndef __APPLE__
227  setWindowIcon (QPixmap(":/bitmaps/big.qucs.xpm"));
228 #endif
229 
230  DocumentTab = new QTabWidget(this);
231  setCentralWidget(DocumentTab);
232 
233  connect(DocumentTab,
234  SIGNAL(currentChanged(QWidget*)), SLOT(slotChangeView(QWidget*)));
235 
236  // Give every tab a close button, and connect the button's signal to
237  // slotFileClose
238  DocumentTab->setTabsClosable(true);
239  connect(DocumentTab,
240  SIGNAL(tabCloseRequested(int)), SLOT(slotFileClose(int)));
241 #ifdef HAVE_QTABWIDGET_SETMOVABLE
242  // make tabs draggable if supported
243  DocumentTab->setMovable (true);
244 #endif
245 
246  //dock = new VTabbedDockWidget(Q3DockWindow::InDock, this);
247  dock = new QDockWidget(this);
248  //TabView = new VTabWidget(VTabInterface::TabLeft,dock); // tabs on the left side
249  TabView = new QTabWidget(dock);
250  TabView->setTabPosition(QTabWidget::West);
251 
252  connect(dock, SIGNAL(visibilityChanged(bool)), SLOT(slotToggleDock(bool)));
253 
254  view = new MouseActions(this);
255 
256  editText = new QLineEdit(this); // for editing component properties
257  editText->setFrame(false);
258  editText->setHidden(true);
259  editText->setPaletteBackgroundColor(QucsSettings.BGColor);
260  connect(editText, SIGNAL(returnPressed()), SLOT(slotApplyCompText()));
261  connect(editText, SIGNAL(textChanged(const QString&)),
262  SLOT(slotResizePropEdit(const QString&)));
263  connect(editText, SIGNAL(lostFocus()), SLOT(slotHideEdit()));
264 
265  // ----------------------------------------------------------
266  // "Project Tab" of the left QTabWidget
267  QWidget *ProjGroup = new QWidget();
268  QVBoxLayout *ProjGroupLayout = new QVBoxLayout();
269  QWidget *ProjButts = new QWidget();
270  QPushButton *ProjNew = new QPushButton(tr("New"));
271  connect(ProjNew, SIGNAL(clicked()), SLOT(slotProjNewButt()));
272  QPushButton *ProjOpen = new QPushButton(tr("Open"));
273  connect(ProjOpen, SIGNAL(clicked()), SLOT(slotProjOpenButt()));
274  QPushButton *ProjDel = new QPushButton(tr("Delete"));
275  connect(ProjDel, SIGNAL(clicked()), SLOT(slotProjDelButt()));
276 
277  QHBoxLayout *ProjButtsLayout = new QHBoxLayout();
278  ProjButtsLayout->addWidget(ProjNew);
279  ProjButtsLayout->addWidget(ProjOpen);
280  ProjButtsLayout->addWidget(ProjDel);
281  ProjButts->setLayout(ProjButtsLayout);
282 
283  ProjGroupLayout->addWidget(ProjButts);
284 
285  Projects = new QListWidget();
286 
287  ProjGroupLayout->addWidget(Projects);
288  ProjGroup->setLayout(ProjGroupLayout);
289 
290  TabView->addTab(ProjGroup, tr("Projects"));
291  TabView->setTabToolTip(TabView->indexOf(ProjGroup), tr("content of project directory"));
292 
293  connect(Projects, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(slotOpenProject(QListWidgetItem*)));
294 
295  // ----------------------------------------------------------
296  // "Content" Tab of the left QTabWidget
297  Content = new QTreeWidget(this);
298  Content->setColumnCount(2);
299  QStringList headers;
300  headers << tr("Content of") << tr("Note");
301  Content->setHeaderLabels(headers);
302  Content->setSortingEnabled(false);
303  Content->setColumnWidth(0,150);
304 
305  // allow for a custom context menu
306  Content->setContextMenuPolicy(Qt::CustomContextMenu);
307 
309 
310  TabView->addTab(Content,tr("Content"));
311  TabView->setTabToolTip(TabView->indexOf(Content), tr("content of current project"));
312 
313 
314  connect(Content, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
315  SLOT(slotOpenContent(QTreeWidgetItem*)));
316 
317  connect(Content, SIGNAL(itemPressed(QTreeWidgetItem*, int)),
318  SLOT(slotSelectSubcircuit(QTreeWidgetItem*)));
319 
320  // ----------------------------------------------------------
321  // "Component" Tab of the left QTabWidget
322  QWidget *CompGroup = new QWidget();
323  QVBoxLayout *CompGroupLayout = new QVBoxLayout();
324 
325  CompChoose = new QComboBox(this);
326  CompComps = new QListWidget(this);
327  CompComps->setViewMode(QListView::IconMode);
328  CompComps->setGridSize(QSize(110,90));
329 
330  CompGroupLayout->addWidget(CompChoose);
331  CompGroupLayout->addWidget(CompComps);
332  CompGroup->setLayout(CompGroupLayout);
333 
334  TabView->addTab(CompGroup,tr("Components"));
335  TabView->setTabToolTip(TabView->indexOf(CompGroup), tr("components and diagrams"));
336  fillComboBox(true);
337 
338  slotSetCompView(0);
339  connect(CompChoose, SIGNAL(activated(int)), SLOT(slotSetCompView(int)));
340  connect(CompComps, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(slotSelectComponent(QListWidgetItem*)));
341  connect(CompComps, SIGNAL(itemPressed(QListWidgetItem*)), SLOT(slotSelectComponent(QListWidgetItem*)));
342 
343  // ----------------------------------------------------------
344  // "Libraries" Tab of the left QTabWidget
345 
346  QWidget *LibGroup = new QWidget ();
347  QVBoxLayout *LibGroupLayout = new QVBoxLayout ();
348  QWidget *LibButts = new QWidget ();
349  QPushButton *LibManage = new QPushButton (tr ("Manage Libraries"));
350  connect(LibManage, SIGNAL(clicked()), SLOT(slotCallLibrary()));
351 
352  QHBoxLayout *LibButtsLayout = new QHBoxLayout();
353  LibButtsLayout->addWidget (LibManage);
354  LibButts->setLayout(LibButtsLayout);
355 
356  LibGroupLayout->addWidget(LibButts);
357 
358 
359  libTreeWidget = new QTreeWidget (this);
360  libTreeWidget->setColumnCount (1);
361  headers.clear ();
362  headers << tr ("Libraries");
363  libTreeWidget->setHeaderLabels (headers);
364 
365  LibGroupLayout->addWidget (libTreeWidget);
366  LibGroup->setLayout (LibGroupLayout);
367 
369 
370  TabView->addTab (LibGroup, tr("Libraries"));
371  TabView->setTabToolTip (TabView->indexOf (CompGroup), tr ("system and user component libraries"));
372 
373  connect(libTreeWidget, SIGNAL(itemPressed (QTreeWidgetItem*, int)),
374  SLOT(slotSelectLibComponent (QTreeWidgetItem*)));
375 
376  // ----------------------------------------------------------
377  // put the tab widget in the dock
378  dock->setWidget(TabView);
379  dock->setAllowedAreas(Qt::LeftDockWidgetArea);
380  this->addDockWidget(Qt::LeftDockWidgetArea, dock);
381  TabView->setCurrentPage(0);
382 
383  // ----------------------------------------------------------
384  // Octave docking window
385  //octDock = new Q3DockWindow(Q3DockWindow::InDock, this);
386  //octDock->setCloseMode(Q3DockWindow::Always);
387  octDock = new QDockWidget();
388 
389  connect(octDock, SIGNAL(visibilityChanged(bool)), SLOT(slotToggleOctave(bool)));
390  octave = new OctaveWindow(octDock);
391  this->addDockWidget(Qt::BottomDockWidgetArea, octDock);
392  this->setCorner(Qt::BottomLeftCorner , Qt::LeftDockWidgetArea);
393  //| Qt::BottomRightCorner
394 
395  // ............................................
396 
397  messageDock = new MessageDock(this);
398 
399  // ............................................
400  readProjects(); // reads all projects and inserts them into the ListBox
401 }
402 
403 // Put all available libraries into ComboBox.
405 {
406  QStringList LibFiles;
407  QStringList::iterator it;
408  QList<QTreeWidgetItem *> topitems;
409 
410  libTreeWidget->clear();
411 
412  // make the system libraries section header
413  QTreeWidgetItem* newitem = new QTreeWidgetItem((QTreeWidget*)0, QStringList("System Libraries"));
414  newitem->setChildIndicatorPolicy (QTreeWidgetItem::DontShowIndicator);
415  QFont sectionFont = newitem->font(0);
416  sectionFont.setItalic (true);
417  sectionFont.setBold (true);
418  newitem->setFont (0, sectionFont);
419 // newitem->setBackground
420  topitems.append (newitem);
421 
422  QDir LibDir(QucsSettings.LibDir);
423  LibFiles = LibDir.entryList(QStringList("*.lib"), QDir::Files, QDir::Name);
424 
425  // create top level library itmes, base on the library names
426  for(it = LibFiles.begin(); it != LibFiles.end(); it++)
427  {
428  ComponentLibrary parsedlibrary;
429 
430  int result = parseComponentLibrary (QucsSettings.LibDir + *it , parsedlibrary);
431  QStringList nameAndFileName;
432  nameAndFileName.append (parsedlibrary.name);
433  nameAndFileName.append (QucsSettings.LibDir + *it);
434 
435  QTreeWidgetItem* newlibitem = new QTreeWidgetItem((QTreeWidget*)0, nameAndFileName);
436 
437  switch (result)
438  {
439  case QUCS_COMP_LIB_IO_ERROR:
440  QMessageBox::critical(0, tr ("Error"), tr("Cannot open \"%1\".").arg (*it));
441  return;
442  case QUCS_COMP_LIB_CORRUPT:
443  QMessageBox::critical(0, tr("Error"), tr("Library is corrupt."));
444  return;
445  default:
446  break;
447  }
448 
449  for (int i = 0; i < parsedlibrary.components.count (); i++)
450  {
451  QStringList compNameAndDefinition;
452 
453  compNameAndDefinition.append (parsedlibrary.components[i].name);
454 
455  QString s = "<Qucs Schematic " PACKAGE_VERSION ">\n";
456 
457  s += "<Components>\n " +
458  parsedlibrary.components[i].modelString + "\n" +
459  "</Components>\n";
460 
461  compNameAndDefinition.append (s);
462  // The following may produce a warning from the compiler about
463  // unused variable newcompitem, ignore it, we pass the pointer
464  // to the parent item in the constructor
465  QTreeWidgetItem* newcompitem = new QTreeWidgetItem(newlibitem, compNameAndDefinition);
466  }
467 
468  topitems.append (newlibitem);
469  }
470 
471 
472  // make the user libraries section header
473  newitem = new QTreeWidgetItem((QTreeWidget*)0, QStringList("User Libraries"));
474  newitem->setChildIndicatorPolicy (QTreeWidgetItem::DontShowIndicator);
475  newitem->setFont (0, sectionFont);
476  topitems.append (newitem);
477 
478  QDir UserLibDir = QDir (QucsSettings.QucsHomeDir.canonicalPath () + "/user_lib/");
479 
480  // if there are user libraries, add them too
481  if(UserLibDir.exists ())
482  {
483  //LibFiles = UserLibDir.entryList("*.lib", QDir::Files, QDir::Name);
484  LibFiles = UserLibDir.entryList(QStringList("*.lib"), QDir::Files, QDir::Name);
485  int UserLibCount = LibFiles.count();
486 
487  if (UserLibCount > 0)
488  {
489 
490  // create top level library itmes, base on the library names
491  for(it = LibFiles.begin(); it != LibFiles.end(); it++)
492  {
493  ComponentLibrary parsedlibrary;
494 
495  int result = parseComponentLibrary (UserLibDir.absolutePath() +"/"+ *it , parsedlibrary);
496  QStringList nameAndFileName;
497  nameAndFileName.append (parsedlibrary.name);
498  nameAndFileName.append (UserLibDir.absolutePath() +"/"+ *it);
499 
500  QTreeWidgetItem* newlibitem = new QTreeWidgetItem((QTreeWidget*)0, nameAndFileName);
501 
502  switch (result)
503  {
504  case QUCS_COMP_LIB_IO_ERROR:
505  QMessageBox::critical(0, tr ("Error"), tr("Cannot open \"%1\".").arg (UserLibDir.absolutePath()+"/" +*it));
506  return;
507  case QUCS_COMP_LIB_CORRUPT:
508  QMessageBox::critical(0, tr("Error"), tr("Library is corrupt."));
509  return;
510  default:
511  break;
512  }
513 
514  for (int i = 0; i < parsedlibrary.components.count (); i++)
515  {
516  QStringList compNameAndDefinition;
517 
518  compNameAndDefinition.append (parsedlibrary.components[i].name);
519 
520  QString s = "<Qucs Schematic " PACKAGE_VERSION ">\n";
521 
522  s += "<Components>\n " +
523  parsedlibrary.components[i].modelString + "\n" +
524  "</Components>\n";
525 
526  compNameAndDefinition.append (s);
527  // The following may produce a warning from the compiler about
528  // unused variable newcompitem, ignore it, we pass the pointer
529  // to the parent item in the constructor
530  QTreeWidgetItem* newcompitem = new QTreeWidgetItem(newlibitem, compNameAndDefinition);
531  }
532 
533  topitems.append (newlibitem);
534  }
535  libTreeWidget->insertTopLevelItems(0, topitems);
536  }
537  else
538  {
539  // make the user libraries section header
540  newitem = new QTreeWidgetItem((QTreeWidget*)0, QStringList("No User Libraries"));
541  sectionFont.setBold (false);
542  newitem->setFont (0, sectionFont);
543  topitems.append (newitem);
544  }
545  }
546  else
547  {
548  // make the user libraries section header
549  newitem = new QTreeWidgetItem((QTreeWidget*)0, QStringList("No User Libraries"));
550  sectionFont.setBold (false);
551  newitem->setFont (0, sectionFont);
552  topitems.append (newitem);
553  }
554 
555  libTreeWidget->insertTopLevelItems(0, topitems);
556 }
557 
558 
559 // ---------------------------------------------------------------
560 // Returns a pointer to the QucsDoc object whose number is "No".
561 // If No < 0 then a pointer to the current document is returned.
563 {
564  QWidget *w;
565  if(No < 0)
566  w = DocumentTab->currentPage();
567  else
568  w = DocumentTab->page(No);
569 
570  if(w) {
571  if(isTextDocument (w))
572  return (QucsDoc*) ((TextDoc*)w);
573  else
574  return (QucsDoc*) ((Schematic*)w);
575  }
576 
577  return 0;
578 }
579 
580 // ---------------------------------------------------------------
581 // Returns a pointer to the QucsDoc object whose file name is "Name".
582 QucsDoc * QucsApp::findDoc (QString File, int * Pos)
583 {
584  QucsDoc * d;
585  int No = 0;
586  File = QDir::convertSeparators (File);
587  while ((d = getDoc (No++)) != 0)
588  if (QDir::convertSeparators (d->DocName) == File) {
589  if (Pos) *Pos = No - 1;
590  return d;
591  }
592  return 0;
593 }
594 
595 // ---------------------------------------------------------------
596 // Put the component groups into the ComboBox. It is possible to
597 // only put the paintings in it, because of "symbol painting mode".
598 
599 // if setAll, add all categories to combobox
600 // if not, set just paintings (symbol painting mode)
601 void QucsApp::fillComboBox (bool setAll)
602 {
603  //CompChoose->setMaxVisibleItems (13); // Increase this if you add items below.
604  CompChoose->clear ();
605 
606  QStringList cats = Category::getCategories ();
607  for (QStringList::Iterator it = cats.begin (); it != cats.end (); ++it) {
608  if (setAll)
609  CompChoose->insertItem (*it);
610  else
611  if (*it == QObject::tr("paintings"))
612  CompChoose->insertItem (*it);
613  }
614 }
615 
616 // ----------------------------------------------------------
617 // Whenever the Component Library ComboBox is changed, this slot fills the
618 // Component IconView with the appropriate components.
619 void QucsApp::slotSetCompView (int index)
620 {
621 // qDebug() << "QucsApp::slotSetCompView (int index)";
622 
623  editText->setHidden (true); // disable text edit of component property
624 
625  Q3PtrList<Module> Comps;
626  CompComps->clear (); // clear the IconView
627  if (CompChoose->count () <= 0) return;
628 
629  QString item = CompChoose->text (index);
630 
631  /*
632  * The following test is used as only paintings are allowed in
633  * symbol editing mode, previously paintings had to be the last
634  * category in modules.cpp.
635  * Howver, before symbol edit is started it is requested that only
636  * 'paintigs' gets added to the 'compChoose' combobox.
637  * See: QucsApp::fillComboBox
638  *
639  */
640 
641  if (item == QObject::tr("paintings"))
642  {
643  // if index beyond count of combobox, assume it is paintings...
644  Comps = Category::getModules (QObject::tr("paintings"));
645  }
646  else
647  {
648  // get list of components, will add the icons to dock
649  Comps = Category::getModules (item);
650  }
651 
652  QString Name;
653 
654  // if something was registered dynamicaly, get and draw icons into dock
655  if (item == QObject::tr("verilog-a user devices")) {
656 
657  QListWidgetItem *icon;
658  QMapIterator<QString, QString> i(Module::vaComponents);
659  while (i.hasNext()) {
660  i.next();
661 
662  // default icon initally matches the module name
663  //Name = i.key();
664 
665  // Just need path to bitmap, do not create an object
666  QString Name, vaBitmap;
667  Component * c = (Component *)
668  vacomponent::info (Name, vaBitmap, false, i.value());
669  if (c) delete c;
670 
671  // check if icon exists, fall back to default
672  QString iconPath = QucsSettings.QucsWorkDir.filePath(vaBitmap+".png");
673 
674  QFile iconFile(iconPath);
675  QPixmap vaIcon;
676 
677  if(iconFile.exists())
678  {
679  // load bitmap defined on the JSON symbol file
680  vaIcon = QPixmap(iconPath);
681  }
682  else
683  {
684  QMessageBox::information(this, tr("Info"),
685  tr("Default icon not found:\n %1.png").arg(vaBitmap));
686  // default icon
687  vaIcon = QPixmap(":/bitmaps/editdelete.png");
688  }
689 
690  // Add icon an name tag to dock
691  icon = new QListWidgetItem(vaIcon, Name);
692  icon->setToolTip(Name);
693  CompComps->addItem(icon);
694  }
695  }
696  else {
697  char * File;
698  Module * Mod;
699  // Populate list of component bitmaps
700  for (Mod = Comps.first(); Mod; Mod = Comps.next ()) {
701  if (Mod->info) {
702  *(Mod->info) (Name, File, false);
703  QListWidgetItem *icon = new QListWidgetItem(QPixmap(":/bitmaps/" + QString (File) + ".png"), Name);
704  icon->setToolTip(Name);
705  CompComps->addItem(icon);
706  }
707  }
708  }
709 }
710 
711 // ------------------------------------------------------------------
712 // Is called when the mouse is clicked within the Component QIconView.
713 void QucsApp::slotSelectComponent(QListWidgetItem *item)
714 {
715  editText->setHidden(true); // disable text edit of component property
716 
717  // delete previously selected elements
718  if(view->selElem != 0) delete view->selElem;
719  view->selElem = 0; // no component/diagram/painting selected
720 
721  if(item == 0) { // mouse button pressed not over an item ?
722  CompComps->clearSelection(); // deselect component in ViewList
723  return;
724  }
725 
726  if(view->drawn)
727  ((Q3ScrollView*)DocumentTab->currentPage())->viewport()->update();
728  view->drawn = false;
729 
730  // toggle last toolbar button off
731  if(activeAction) {
732  activeAction->blockSignals(true); // do not call toggle slot
733  activeAction->setOn(false); // set last toolbar button off
734  activeAction->blockSignals(false);
735  }
736  activeAction = 0;
737 
740  MouseReleaseAction = 0;
742 
743  pInfoFunc Infos = 0;
744 
745  pInfoVAFunc InfosVA = 0;
746 
747  int i = CompComps->row(item);
748  Q3PtrList<Module> Comps;
749 
750  // if symbol mode, only paintings are enabled.
751  if (CompChoose->currentText() == QObject::tr("paintings"))
752  Comps = Category::getModules (QObject::tr("paintings"));
753  else {
754  Comps = Category::getModules (CompChoose->currentText ());
755  qDebug() << "pressed CompComps id" << i;
756  qDebug() << CompComps->item(i)->toolTip(); //Name;
757 
758  }
759 
760  // handle static and dynamic components
761  if (CompChoose->currentText() == QObject::tr("verilog-a user devices")){
762  InfosVA = Comps.at(i)->infoVA;
763 
764  // get JSON file out of item name on toolTip
765  QString name = CompComps->item(i)->toolTip();
766  QString filename = Module::vaComponents[name];
767 
768  QString Dummy1;
769  QString Dummy2;
770  if (InfosVA) {
771  qDebug() << " slotSelectComponent, view->selElem" ;
772  view->selElem = (*InfosVA) (Dummy1, Dummy2, true, filename);
773  }
774 
775  }
776  else {
777  Infos = Comps.at(i)->info;
778 
779  char * Dummy2;
780  QString Dummy1;
781  if (Infos)
782  view->selElem = (*Infos) (Dummy1, Dummy2, true);
783  }
784 }
785 
786 // ####################################################################
787 // ##### Functions for the menu that appears when right-clicking #####
788 // ##### on a file in the "Content" ListView. #####
789 // ####################################################################
790 
792 {
793 
794  // TODO -> The contentmenu is also shown when the user right-clicks on a category...
795  ContentMenu = new QMenu(this);
796 
797  ActionCMenuOpen = new QAction(tr("Open"), ContentMenu);
798  connect(ActionCMenuOpen, SIGNAL(triggered()), this, SLOT(slotCMenuOpen()));
799  ContentMenu->addAction(ActionCMenuOpen);
800 
801  ActionCMenuCopy = new QAction(tr("Duplicate"), ContentMenu);
802  connect(ActionCMenuCopy, SIGNAL(triggered()), this, SLOT(slotCMenuCopy()));
803  ContentMenu->addAction(ActionCMenuCopy);
804 
805  ActionCMenuRename = new QAction(tr("Rename"), ContentMenu);
806  connect(ActionCMenuRename, SIGNAL(triggered()), this, SLOT(slotCMenuRename()));
807  ContentMenu->addAction(ActionCMenuRename);
808 
809  ActionCMenuDelete = new QAction(tr("Delete"), ContentMenu);
810  connect(ActionCMenuDelete, SIGNAL(triggered()), this, SLOT(slotCMenuDelete()));
811  ContentMenu->addAction(ActionCMenuDelete);
812 
813  ActionCMenuInsert = new QAction(tr("Insert"), ContentMenu);
814  connect(ActionCMenuInsert, SIGNAL(triggered()), this, SLOT(slotCMenuInsert()));
815  ContentMenu->addAction(ActionCMenuInsert);
816 
817 
818  // TODO -> not implemented yet...
819  //ActionCMenuDelGroup = new QAction(tr("Delete Group"), ContentMenu);
820  //connect(ActionCMenuDelGroup, SIGNAL(triggered()), this, SLOT(slotCMenuDelGroup()));
821  //Content->addAction(ActionCMenuDelGroup);
822 
823 
824  connect(Content, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(slotShowContentMenu(const QPoint&)));
825 }
826 
827 // ----------------------------------------------------------
828 // Shows the menu.
829 void QucsApp::slotShowContentMenu(const QPoint& pos) {
830 
831  QTreeWidgetItem *item = Content->currentItem();
832  if(item->text(1 ).contains(tr("-port")))
833  {
834  ActionCMenuInsert->setVisible(true);
835  }
836  else
837  {
838  ActionCMenuInsert->setVisible(false);
839  }
840 
841  // only show contentmenu when child is selected...
842  if(item->parent()!= 0) {
843  ContentMenu->popup(Content->mapToGlobal(pos));
844  }
845 
846 }
847 /* OLD Version
848 void QucsApp::slotShowContentMenu(Q3ListViewItem *item, const QPoint& point, int)
849 {
850  if(item)
851  if(item->parent() != 0) { // no component, but item "schematic", ...
852  if(item->parent()->nextSibling()) // "Others" section in listview ?
853  ContentMenu->setItemEnabled(ContentMenu->idAt(3), true);
854  else
855  ContentMenu->setItemEnabled(ContentMenu->idAt(3), false);
856  ContentMenu->popup(point);
857  }
858 }
859 */
860 // ----------------------------------------------------------
862 {
863  QTreeWidgetItem *Item = Content->currentItem();
864  if(Item == 0) return;
865 
866  slotOpenContent(Item);
867 }
868 
869 // ----------------------------------------------------------
871 {
872  QTreeWidgetItem *Item = Content->currentItem();
873  if(Item == 0) return;
874 
875  QString Name = Item->text(0);
876  QString currentPath = QucsSettings.QucsWorkDir.filePath(Name);
877  QString Path = currentPath.section(QDir::separator(), 0, -2);
878 
879  //check changed file save
880  int z = 0; //search if the doc is loaded
881  QucsDoc *d = findDoc(currentPath, &z);
882  if (d != NULL && d->DocChanged) {
883  DocumentTab->setCurrentPage(z);
884  int ret = QMessageBox::question(this, tr("Copying Qucs document"),
885  tr("The document contains unsaved changes!\n") +
886  tr("Do you want to save the changes before copying?"),
887  tr("&Ignore"), tr("&Save"), 0, 1);
888  if (ret == 1) {
889  d->save();
890  }
891  }
892 
893  QString Suffix = Name.section('.',-1); // remember suffix
894  QString Base = Name.section('.',0,-2);
895  if(Base.isEmpty()) Base = Name;
896 
897  bool exists = true; //generate unique name
898  int i = 0;
899  QString defaultName;
900  while (exists) {
901  ++i;
902  defaultName = Base + "_copy" + QString::number(i) + "." + Suffix;
903  exists = QFile::exists (Path + QDir::separator() + defaultName);
904  }
905 
906  bool ok;
907  QString s = QInputDialog::getText(tr("Copy file"), tr("Enter new name:"),
908  QLineEdit::Normal, defaultName, &ok, this);
909  if(!ok) return;
910  if(s.isEmpty()) return;
911 
912  QString NewName;
913  if(s.contains('.'))
914  NewName = s;
915  else
916  NewName = s+"."+Suffix;
917 
918  if (QFile::exists(Path + QDir::separator() + NewName)) { //check New Name exists
919  QMessageBox::critical(this, tr("error"), tr("Cannot copy file to identical name: ") + Name);
920  return;
921  }
922 
923  if (!QFile::copy(Path + QDir::separator() + Name,
924  Path + QDir::separator() + NewName)) {
925  QMessageBox::critical(this, tr("Error"), tr("Cannot copy schematic: ")+Name);
926  return;
927  }
928  //TODO: maybe require disable edit here
929 
930  // refresh the schematic file path
931  this->updateSchNameHash();
932  this->updateSpiceNameHash();
933 
934  if(!ProjName.isEmpty())
935  readProjectFiles(); // re-read the content ListView
936 }
937 
938 // ----------------------------------------------------------
940 {
941  QTreeWidgetItem *Item = Content->currentItem();
942  if(!Item) return;
943 
944  QString Name = Item->text(0);
945  if (findDoc (QucsSettings.QucsWorkDir.filePath(Name))) {
946  QMessageBox::critical(this, tr("Error"),
947  tr("Cannot rename an open file!"));
948  return;
949  }
950 
951  QString Suffix = Name.section('.',-1); // remember suffix
952  QString Base = Name.section('.',0,-2);
953  if(Base.isEmpty()) Base = Name;
954 
955  bool ok;
956  QString s = QInputDialog::getText(tr("Rename file"), tr("Enter new name:"),
957  QLineEdit::Normal, Base, &ok, this);
958  if(!ok) return;
959  if(s.isEmpty()) return;
960 
961  QString NewName;
962  if(s.contains('.'))
963  NewName = s;
964  else
965  NewName = s+"."+Suffix;
966  QDir file(QucsSettings.QucsWorkDir.path());
967  if(!file.rename(Name, NewName)) {
968  QMessageBox::critical(this, tr("Error"), tr("Cannot rename file: ")+Name);
969  return;
970  }
971  Item->setText(0, NewName);
972 }
973 
974 // ----------------------------------------------------------
976 {
977  QTreeWidgetItem *item = Content->currentItem();
978  if(item == 0) return;
979  QString FileName = QucsSettings.QucsWorkDir.filePath(item->text(0));
980 
981  if (findDoc (FileName)) {
982  QMessageBox::critical(this, tr("Error"),
983  tr("Cannot delete an open file!"));
984  return;
985  }
986 
987  int No;
988  No = QMessageBox::warning(this, tr("Warning"),
989  tr("This will delete the file permanently! Continue ?"),
990  tr("No"), tr("Yes"));
991  if(No != 1) return;
992 
993  if(!QFile::remove(FileName)) {
994  QMessageBox::critical(this, tr("Error"),
995  tr("Cannot delete schematic: ")+item->text(0));
996  return;
997  }
998 
999  delete item;
1000 }
1001 
1002 // ----------------------------------------------------------
1003 QString QucsApp::fileType (const QString& Ext)
1004 {
1005  QString Type = tr("unknown");
1006  if (Ext == "v")
1007  Type = tr("Verilog source");
1008  else if (Ext == "va")
1009  Type = tr("Verilog-A source");
1010  else if (Ext == "vhd" || Ext == "vhdl")
1011  Type = tr("VHDL source");
1012  else if (Ext == "dat")
1013  Type = tr("data file");
1014  else if (Ext == "dpl")
1015  Type = tr("data display");
1016  else if (Ext == "sch")
1017  Type = tr("schematic");
1018  else if (Ext == "sym")
1019  Type = tr("symbol");
1020  else if (Ext == "vhdl.cfg" || Ext == "vhd.cfg")
1021  Type = tr("VHDL configuration");
1022  else if (Ext == "cfg")
1023  Type = tr("configuration");
1024  return Type;
1025 }
1026 
1027 // ----------------------------------------------------------
1028 // TODO -> not implemented yet
1029 // Deletes all files with that name (and suffix sch, dpl, dat, vhdl, etc.).
1031 {
1032  QTreeWidgetItem *item = Content->currentItem();
1033  if (item == 0)
1034  return;
1035  QString s = item->text (0);
1036  s = QucsDoc::fileBase (s); // cut off suffix from file name
1037 
1038  const char * extensions[] =
1039  { "sch", "dpl", "dat", "vhdl", "vhd", "v", "sym",
1040  "vhdl.cfg", "vhd.cfg", "va", 0 };
1041 
1042  int i;
1043  for (i = 0; extensions[i] != 0; i++) {
1044  QString Short = s + "." + extensions[i];
1045  QString Name = QucsSettings.QucsWorkDir.filePath (Short);
1046  // search, if files are open
1047  if (findDoc (Name)) {
1048  QMessageBox::critical(this, tr("Error"), tr("Cannot delete the open file \"%1\"!").arg(Short));
1049  return;
1050  }
1051  }
1052 
1053 
1054 
1055  // check existence of files
1056  QString Str = "\n";
1057  for (i = 0; extensions[i] != 0; i++) {
1058  QString Short = s + "." + extensions[i];
1059  QString Long = QucsSettings.QucsWorkDir.filePath (Short);
1060  bool exists = QFile::exists (Long);
1061  if (exists)
1062  Str += Short + "\n";
1063  }
1064  int No;
1065  No = QMessageBox::warning (this, tr("Warning"),
1066  tr("This will delete the files%1permanently! Continue ?").arg(Str),
1067  tr("No"), tr("Yes"));
1068  if (No != 1)
1069  return;
1070 
1071  // file removal
1072  for (i = 0; extensions[i] != 0; i++) {
1073  QString Short = s + "." + extensions[i];
1074  QString Name = QucsSettings.QucsWorkDir.filePath (Short);
1075  bool exists = QFile::exists (Name);
1076  if (exists) {
1077  // remove files
1078  if (!QFile::remove (Name)) {
1079  QMessageBox::critical(this, tr("Error"), tr("Cannot delete %1: \"%2\"!").arg(fileType (extensions[i])).
1080  arg(Short));
1081  continue;
1082  }
1083  // remove items from listview
1084  //item = Content->findItem (Short, 0);
1085  if (item) {
1086  // TODO???
1087  //item->parent()->takeItem (item);
1088  delete item;
1089  }
1090  }
1091  }
1092 }
1093 
1094 
1095 // ----------------------------------------------------------
1096 // Inserts the selected subschematic in the schematic
1098 {
1099  slotSelectSubcircuit(Content->currentItem());
1100 }
1101 
1102 // ################################################################
1103 // ##### Functions that handle the project operations. #####
1104 // ################################################################
1105 
1106 // Checks for qucs directory and reads all existing Qucs projects.
1108 {
1109  QDir ProjDir(QucsSettings.QucsHomeDir);
1110  if(!ProjDir.cd(QucsSettings.QucsHomeDir.absolutePath())) { // work directory exists ?
1111  if(!ProjDir.mkdir(QucsSettings.QucsHomeDir.absolutePath())) { // no, then create it
1112  QMessageBox::warning(this, tr("Warning"),
1113  tr("Cannot create work directory !"));
1114  return;
1115  }
1116  ProjDir.cd(QucsSettings.QucsHomeDir.absolutePath());
1117  }
1118 
1119  // get all directories
1120  QStringList PrDirs = ProjDir.entryList("*", QDir::Dirs, QDir::Name);
1121  PrDirs.pop_front(); // delete "." from list
1122  PrDirs.pop_front(); // delete ".." from list
1123 
1124  Projects->clear();
1125  QStringList::iterator it;
1126  // inserts all project directories
1127  for(it = PrDirs.begin(); it != PrDirs.end(); it++)
1128  if ((*it).right(4) == "_prj") { // project directories end with "_prj"
1129  (*it) = (*it).left((*it).length()-4); // remove "_prj" from name
1130  Projects->addItem(*it);
1131  }
1132 }
1133 
1134 // ----------------------------------------------------------
1135 // Is called, when "Create New Project" button is pressed.
1137 {
1138  editText->setHidden(true); // disable text edit of component property
1139 
1140  NewProjDialog *d = new NewProjDialog(this);
1141  if(d->exec() != QDialog::Accepted) return;
1142 
1143  QDir projDir(QucsSettings.QucsHomeDir.path());
1144  if(projDir.mkdir(d->ProjName->text()+"_prj")) {
1145  Projects->insertItem(0, d->ProjName->text()); // at first position
1146  if(d->OpenProj->isChecked())
1147  slotOpenProject(Projects->item(0));
1148  }
1149  else QMessageBox::information(this, tr("Info"),
1150  tr("Cannot create project directory !"));
1151 }
1152 
1153 // ----------------------------------------------------------
1154 // Checks whether this file is a qucs file and whether it is an subcircuit.
1155 // It returns the number of subcircuit ports.
1156 int QucsApp::testFile(const QString& DocName)
1157 {
1158  QFile file(DocName);
1159  if(!file.open(QIODevice::ReadOnly)) {
1160  return -1;
1161  }
1162 
1163  QString Line;
1164  // .........................................
1165  // To strongly speed up the file read operation the whole file is
1166  // read into the memory in one piece.
1167  QTextStream ReadWhole(&file);
1168  QString FileString = ReadWhole.read();
1169  file.close();
1170  QTextStream stream(&FileString, QIODevice::ReadOnly);
1171 
1172 
1173  // read header ........................
1174  do {
1175  if(stream.atEnd()) {
1176  file.close();
1177  return -2;
1178  }
1179  Line = stream.readLine();
1180  Line = Line.stripWhiteSpace();
1181  } while(Line.isEmpty());
1182 
1183  if(Line.left(16) != "<Qucs Schematic ") { // wrong file type ?
1184  file.close();
1185  return -3;
1186  }
1187 
1188  Line = Line.mid(16, Line.length()-17);
1189  if(!checkVersion(Line)) { // wrong version number ?
1191  file.close();
1192  return -4;
1193  }
1194  //file.close();
1195  //return -4;
1196  }
1197 
1198  // read content ....................
1199  while(!stream.atEnd()) {
1200  Line = stream.readLine();
1201  if(Line == "<Components>") break;
1202  }
1203 
1204  int z=0;
1205  while(!stream.atEnd()) {
1206  Line = stream.readLine();
1207  if(Line == "</Components>") {
1208  file.close();
1209  return z; // return number of ports
1210  }
1211 
1212  Line = Line.stripWhiteSpace();
1213  QString s = Line.section(' ',0,0); // component type
1214  if(s == "<Port") z++;
1215  }
1216  return -5; // component field not closed
1217 }
1218 
1219 // ----------------------------------------------------------
1220 // Reads all files in the project directory and sort them into the
1221 // content ListView
1223 {
1224  // Delete the content files, but don't delete the parent items !!!
1225 /* TODO
1226  while(ConSchematics->firstChild())
1227  delete ConSchematics->firstChild();
1228  while(ConDisplays->firstChild())
1229  delete ConDisplays->firstChild();
1230  while(ConDatasets->firstChild())
1231  delete ConDatasets->firstChild();
1232  while(ConSources->firstChild())
1233  delete ConSources->firstChild();
1234  while(ConVerilog->firstChild())
1235  delete ConVerilog->firstChild();
1236  while(ConVerilogA->firstChild())
1237  delete ConVerilogA->firstChild();
1238  while(ConOthers->firstChild())
1239  delete ConOthers->firstChild();
1240  while(ConOctave->firstChild())
1241  delete ConOctave->firstChild();
1242 */
1243 
1244  //Is this OK instead of the above??
1246 
1247  int n;
1248  // put all files into "Content"-ListView
1249  QStringList Elements = QucsSettings.QucsWorkDir.entryList("*", QDir::Files, QDir::Name);
1250  QStringList::iterator it;
1251  QString Str;
1252  ConSchematics->setExpanded(true);
1253  for(it = Elements.begin(); it != Elements.end(); ++it) {
1254  Str = QucsDoc::fileSuffix (*it);
1255  if(Str == "sch") {
1256  n = testFile(QucsSettings.QucsWorkDir.filePath((*it).ascii()));
1257  if(n >= 0) {
1258  if(n > 0) {
1259  QTreeWidgetItem *temp = new QTreeWidgetItem(ConSchematics);
1260  temp->setText(0, (*it).ascii());
1261  temp->setText(1, QString::number(n)+tr("-port"));
1262  }
1263  else {
1264  QTreeWidgetItem *temp = new QTreeWidgetItem(ConSchematics);
1265  temp->setText(0, (*it).ascii());
1266  }
1267  }
1268  }
1269  else if(Str == "dpl") {
1270  QTreeWidgetItem *temp = new QTreeWidgetItem(ConDisplays);
1271  temp->setText(0, (*it).ascii());
1272  }
1273  else if(Str == "dat") {
1274  QTreeWidgetItem *temp = new QTreeWidgetItem(ConDatasets);
1275  temp->setText(0, (*it).ascii());
1276  }
1277  else if((Str == "vhdl") || (Str == "vhd")) {
1278  QTreeWidgetItem *temp = new QTreeWidgetItem(ConSources);
1279  temp->setText(0, (*it).ascii());
1280  }
1281  else if(Str == "v") {
1282  QTreeWidgetItem *temp = new QTreeWidgetItem(ConVerilog);
1283  temp->setText(0, (*it).ascii());
1284  }
1285  else if(Str == "va") {
1286  QTreeWidgetItem *temp = new QTreeWidgetItem(ConVerilogA);
1287  temp->setText(0, (*it).ascii());
1288  }
1289  else if((Str == "m") || (Str == "oct")) {
1290  QTreeWidgetItem *temp = new QTreeWidgetItem(ConOctave);
1291  temp->setText(0, (*it).ascii());
1292  }
1293  else {
1294  QTreeWidgetItem *temp = new QTreeWidgetItem(ConOthers);
1295  temp->setText(0, (*it).ascii());
1296  }
1297  }
1298 }
1299 
1300 // ----------------------------------------------------------
1301 // Opens an existing project.
1302 void QucsApp::openProject(const QString& Path, const QString& Name)
1303 {
1304  editText->setHidden(true); // disable text edit of component property
1305 
1306  if(!closeAllFiles()) return; // close files and ask for saving them
1307  new Schematic(this, "");
1308  view->drawn = false;
1309 
1311 
1312  QDir ProjDir(QDir::cleanDirPath(Path));
1313  if(!ProjDir.exists() || !ProjDir.isReadable()) { // check project directory
1314  QMessageBox::critical(this, tr("Error"),
1315  tr("Cannot access project directory: ")+Path);
1316  return;
1317  }
1318  QucsSettings.QucsWorkDir.setPath(ProjDir.path());
1320 
1321  QStringList headers;
1322  headers << tr("Content of ") + Name << tr("Note");
1323  Content->setHeaderLabels(headers);
1324 
1325  readProjectFiles();
1326 
1327  TabView->setCurrentPage(1); // switch to "Content"-Tab
1328  ProjName = Name; // remember the name of project
1329 
1330  // show name in title of main window
1331  setCaption("Qucs " PACKAGE_VERSION + tr(" - Project: ")+Name);
1332 }
1333 
1334 // ----------------------------------------------------------
1335 // Is called when the open project menu is called.
1337 {
1338  QString d = QFileDialog::getExistingDirectory(this, tr("Choose Project Directory for Opening"),
1339  QucsSettings.QucsHomeDir.path(),
1340  QFileDialog::ShowDirsOnly
1341  | QFileDialog::DontResolveSymlinks);
1342  QString s = d;
1343  if(s.isEmpty()) return;
1344 
1345  s = s.left(s.length()-1); // cut off trailing '/'
1346  int i = s.findRev('/');
1347  if(i > 0) s = s.mid(i+1); // cut out the last subdirectory
1348  s.remove("_prj");
1349  openProject(d, s);
1350 }
1351 
1352 // ----------------------------------------------------------
1353 // Is called, when "Open Project" button is pressed.
1355 {
1356  editText->setHidden(true); // disable text edit of component property
1357 
1358  QListWidgetItem *item = Projects->currentItem();
1359  if(item) slotOpenProject(item);
1360  else QMessageBox::information(this, tr("Info"),
1361  tr("No project is selected !"));
1362 }
1363 
1364 // ----------------------------------------------------------
1365 // Is called when project is double-clicked to open it.
1366 void QucsApp::slotOpenProject(QListWidgetItem *item)
1367 {
1368  openProject(QucsSettings.QucsHomeDir.filePath(item->text()+"_prj"), item->text());
1369 }
1370 
1371 // ----------------------------------------------------------
1372 // Is called when the close project menu is called.
1374 {
1375  editText->setHidden(true); // disable text edit of component property
1376 
1377  if(!closeAllFiles()) return; // close files and ask for saving them
1378  new Schematic(this, "");
1379  view->drawn = false;
1380 
1382  setCaption("Qucs " PACKAGE_VERSION + tr(" - Project: "));
1383  QucsSettings.QucsWorkDir.setPath(QDir::homeDirPath()+QDir::convertSeparators ("/.qucs"));
1385 
1386  QStringList headers;
1387  headers << tr("Content of") << tr("Note");
1388  Content->setHeaderLabels(headers);
1389 
1391 
1392  TabView->setCurrentPage(0); // switch to "Projects"-Tab
1393  ProjName = "";
1394 }
1395 
1396 // ----------------------------------------------------------
1398 {
1399  // removes every file, remove("*") does not work
1400  QStringList Files = Dir.entryList("*", QDir::Files|QDir::Hidden); // all files
1401  QStringList::iterator it;
1402  for(it = Files.begin(); it != Files.end(); it++) {
1403  if(!Dir.remove(*it)) {
1404  QMessageBox::information(this, tr("Info"),
1405  tr("Cannot delete file: ")+(*it));
1406  return false;
1407  }
1408  }
1409 
1410  QDir myDir(Dir);
1411  // Remove all directories recursively.
1412  Files = Dir.entryList("*", QDir::Dirs);
1413  Files.pop_front(); // delete "." from list
1414  Files.pop_front(); // delete ".." from list
1415  for(it = Files.begin(); it != Files.end(); it++) {
1416  myDir.cd(*it);
1417  if(!deleteDirectoryContent(myDir))
1418  return false;
1419  myDir.cdUp();
1420  if(!myDir.rmdir(*it)) {
1421  QMessageBox::information(this, tr("Info"),
1422  tr("Cannot remove directory: ")+(*it));
1423  return false;
1424  }
1425  }
1426  return true;
1427 }
1428 
1429 // ----------------------------------------------------------
1430 bool QucsApp::deleteProject(const QString& Path, const QString& Name)
1431 {
1432  editText->setHidden(true); // disable text edit of component property
1433 
1434  if(Name == ProjName) {
1435  QMessageBox::information(this, tr("Info"),
1436  tr("Cannot delete an open project !"));
1437  return false;
1438  }
1439 
1440  // first ask, if really delete project ?
1441  if(QMessageBox::warning(this, tr("Warning"),
1442  tr("This will destroy all the project files permanently ! Continue ?"),
1443  tr("&Yes"), tr("&No"), 0,1,1)) return false;
1444 
1445  QDir projDir = QDir(Path);
1446  if(!deleteDirectoryContent(projDir))
1447  return false;
1448 
1449  projDir.cdUp(); // leave project directory for deleting
1450  if(!projDir.rmdir(Name+"_prj")) {
1451  QMessageBox::information(this, tr("Info"),
1452  tr("Cannot remove project directory !"));
1453  return false;
1454  }
1455 
1456  return true;
1457 }
1458 
1459 // ----------------------------------------------------------
1460 // Is called, when "Delete Project" menu is activated.
1462 {
1463 
1464  QString d = QFileDialog::getExistingDirectory(this, tr("Choose Project Directory for Deleting"),
1465  QucsSettings.QucsHomeDir.path(),
1466  QFileDialog::ShowDirsOnly
1467  | QFileDialog::DontResolveSymlinks);
1468  QString s = d;
1469 
1470  if(s.isEmpty()) return;
1471 
1472  if (s.endsWith(QDir::separator())) {
1473  s = s.left(s.length()-1); // cut off trailing '/'
1474  }
1475  int i = s.findRev(QDir::separator());
1476  if(i > 0) s = s.mid(i+1); // cut out the last subdirectory
1477  s.chop(4); // remove "_prj" from name
1478  deleteProject(d, s);
1479  readProjects(); // re-reads all projects and inserts them into the ListBox
1480 }
1481 
1482 // ----------------------------------------------------------
1483 // Is called, when "Delete Project" button is pressed.
1485 {
1486  QListWidgetItem *item = Projects->currentItem();
1487  if(!item) {
1488  QMessageBox::information(this, tr("Info"),
1489  tr("No project is selected !"));
1490  return;
1491  }
1492 
1493  if(!deleteProject(QucsSettings.QucsHomeDir.filePath(item->text()+"_prj"),
1494  item->text())) return;
1495  Projects->takeItem(Projects->currentRow()); // remove from project list
1496 }
1497 
1498 
1499 // ################################################################
1500 // ##### Functions that handle the file operations for the #####
1501 // ##### documents. #####
1502 // ################################################################
1503 
1505 {
1506  statusBar()->message(tr("Creating new schematic..."));
1507  editText->setHidden(true); // disable text edit of component property
1508 
1509  new Schematic(this, "");
1510 
1511  statusBar()->message(tr("Ready."));
1512 }
1513 
1514 // --------------------------------------------------------------
1516 {
1517  statusBar()->message(tr("Creating new text editor..."));
1518  editText->setHidden(true); // disable text edit of component property
1519  new TextDoc(this, "");
1520 
1521  statusBar()->message(tr("Ready."));
1522 }
1523 
1524 // --------------------------------------------------------------
1525 // Changes to the document "Name". If already open then it goes to it
1526 // directly, otherwise it loads it.
1527 bool QucsApp::gotoPage(const QString& Name)
1528 {
1529  int No = DocumentTab->currentPageIndex();
1530 
1531  int i = 0;
1532  QucsDoc * d = findDoc (Name, &i); // search, if page is already loaded
1533 
1534  if(d) { // open page found ?
1535  d->becomeCurrent(true);
1536  DocumentTab->setCurrentPage(i); // make new document the current
1537  return true;
1538  }
1539 
1540  QFileInfo Info(Name);
1541  if(Info.extension(false) == "sch" || Info.extension(false) == "dpl" ||
1542  Info.extension(false) == "sym")
1543  d = new Schematic(this, Name);
1544  else
1545  d = new TextDoc(this, Name);
1546 
1547  if(!d->load()) { // load document if possible
1548  delete d;
1549  DocumentTab->setCurrentPage(No);
1550  view->drawn = false;
1551  return false;
1552  }
1553  slotChangeView(DocumentTab->currentPage());
1554 
1555  // if only an untitled document was open -> close it
1556  if(getDoc(0)->DocName.isEmpty())
1557  if(!getDoc(0)->DocChanged)
1558  delete DocumentTab->page(0);
1559 
1560  view->drawn = false;
1561  return true;
1562 }
1563 
1564 QString lastDirOpenSave; // to remember last directory and file
1565 
1566 // --------------------------------------------------------------
1568 {
1569  editText->setHidden(true); // disable text edit of component property
1570 
1571  statusBar()->message(tr("Opening file..."));
1572 
1573  QString s = QFileDialog::getOpenFileName(this, tr("Enter a Schematic Name"),
1574  lastDirOpenSave.isEmpty() ? QString(".") : lastDirOpenSave, QucsFileFilter);
1575 
1576  if(s.isEmpty())
1577  statusBar()->message(tr("Opening aborted"), 2000);
1578  else {
1579 
1580 
1581 
1582 
1585 
1586  gotoPage(s);
1587  lastDirOpenSave = s; // remember last directory and file
1588 
1589 
1590  statusBar()->message(tr("Ready."));
1591  }
1592 }
1593 
1594 // --------------------------------------------------------------
1596 {
1597  if(!Doc)
1598  Doc = getDoc();
1599 
1600  if(Doc->DocName.isEmpty())
1601  return saveAs();
1602 
1603  int Result = Doc->save();
1604  if(Result < 0) return false;
1605 
1606  updatePortNumber(Doc, Result);
1607  return true;
1608 }
1609 
1610 // --------------------------------------------------------------
1612 {
1613  statusBar()->message(tr("Saving file..."));
1614  DocumentTab->blockSignals(true); // no user interaction during that time
1615  editText->setHidden(true); // disable text edit of component property
1616 
1617  if(!saveFile()) {
1618  DocumentTab->blockSignals(false);
1619  statusBar()->message(tr("Saving aborted"), 2000);
1620  statusBar()->message(tr("Ready."));
1621  return;
1622  }
1623 
1624  DocumentTab->blockSignals(false);
1625  statusBar()->message(tr("Ready."));
1626 
1627  if(!ProjName.isEmpty())
1628  readProjectFiles(); // re-read the content ListView
1629 }
1630 
1631 // --------------------------------------------------------------
1633 {
1634  QWidget *w = DocumentTab->currentPage();
1635  QucsDoc *Doc = getDoc();
1636 
1637  int n = -1;
1638  bool intoView = true;
1639  QString s, Filter;
1640  QFileInfo Info;
1641  while(true) {
1642  intoView = true;
1643  s = Doc->DocName;
1644  Info.setFile(s);
1645  if(s.isEmpty()) { // which is default directory ?
1646  if(ProjName.isEmpty()) {
1647  if(lastDirOpenSave.isEmpty()) s = QDir::currentDirPath();
1648  else s = lastDirOpenSave;
1649  }
1650  else s = QucsSettings.QucsWorkDir.path();
1651  }
1652 
1653  // list of known file extensions
1654  QString ext = "vhdl;vhd;v;va;sch;dpl;m;oct;net;qnet;txt";
1655  QStringList extlist = QStringList::split (';', ext);
1656 
1657  if(isTextDocument (w))
1658  Filter = tr("VHDL Sources")+" (*.vhdl *.vhd);;" +
1659  tr("Verilog Sources")+" (*.v);;"+
1660  tr("Verilog-A Sources")+" (*.va);;"+
1661  tr("Octave Scripts")+" (*.m *.oct);;"+
1662  tr("Qucs Netlist")+" (*.net *.qnet);;"+
1663  tr("Plain Text")+" (*.txt);;"+
1664  tr("Any File")+" (*)";
1665  else
1666  Filter = QucsFileFilter;
1667 
1668  s = QFileDialog::getSaveFileName(this, tr("Enter a Document Name"),
1669  QucsSettings.QucsWorkDir.absPath(),
1670  Filter);
1671  if(s.isEmpty()) return false;
1672  Info.setFile(s); // try to guess the best extension ...
1673  ext = Info.extension(false);
1674 
1675  if(ext.isEmpty() || !extlist.contains(ext))
1676  {
1677  // if no extension was specified or is unknown
1678  if (!isTextDocument (w))
1679  {
1680  // assume it is a schematic
1681  s += ".sch";
1682  }
1683  }
1684 
1685  Info.setFile(s);
1686  if(QFile::exists(s)) {
1687  n = QMessageBox::warning(this, tr("Warning"),
1688  tr("The file '")+Info.fileName()+tr("' already exists!\n")+
1689  tr("Saving will overwrite the old one! Continue?"),
1690  tr("No"), tr("Yes"), tr("Cancel"));
1691  if(n == 2) return false; // cancel
1692  if(n == 0) continue;
1693  intoView = false; // file already exists
1694  }
1695 
1696  // search, if document is open
1697  QucsDoc * d = findDoc (s);
1698  if(d) {
1699  QMessageBox::information(this, tr("Info"),
1700  tr("Cannot overwrite an open document"));
1701  return false;
1702  }
1703 
1704  break;
1705  }
1706  Doc->setName(s);
1707  lastDirOpenSave = Info.dirPath(true); // remember last directory and file
1708 
1709  if(intoView) { // insert new name in Content ListView ?
1710  if(Info.dirPath(true) == QucsSettings.QucsWorkDir.absPath())
1711  if(!ProjName.isEmpty()) {
1712  s = Info.fileName(); // remove path from file name
1713  QString ext = Info.extension (false);
1714  /*
1715  if(ext == "sch")
1716  Content->setSelected(new Q3ListViewItem(ConSchematics, s), true);
1717  else if(ext == "dpl")
1718  Content->setSelected(new Q3ListViewItem(ConDisplays, s), true);
1719  else if(ext == "dat")
1720  Content->setSelected(new Q3ListViewItem(ConDatasets, s), true);
1721  else if((ext == "vhdl") || (ext == "vhd"))
1722  Content->setSelected(new Q3ListViewItem(ConSources, s), true);
1723  else if(ext == "v")
1724  Content->setSelected(new Q3ListViewItem(ConVerilog, s), true);
1725  else if(ext == "va")
1726  Content->setSelected(new Q3ListViewItem(ConVerilogA, s), true);
1727  else if(ext == "m" || ext == "oct")
1728  Content->setSelected(new Q3ListViewItem(ConOctave, s), true);
1729  else
1730  Content->setSelected(new Q3ListViewItem(ConOthers, s), true);
1731 */
1732  }
1733  }
1734 
1735  n = Doc->save(); // SAVE
1736  if(n < 0) return false;
1737 
1738  updatePortNumber(Doc, n);
1739  return true;
1740 }
1741 
1742 // --------------------------------------------------------------
1744 {
1745  statusBar()->message(tr("Saving file under new filename..."));
1746  DocumentTab->blockSignals(true); // no user interaction during the time
1747  editText->setHidden(true); // disable text edit of component property
1748 
1749  if(!saveAs()) {
1750  DocumentTab->blockSignals(false);
1751  statusBar()->message(tr("Saving aborted"), 3000);
1752  statusBar()->message(tr("Ready."));
1753  return;
1754  }
1755 
1756  DocumentTab->blockSignals(false);
1757  statusBar()->message(tr("Ready."));
1758 
1759  // refresh the schematic file path
1760  this->updateSchNameHash();
1761  this->updateSpiceNameHash();
1762 
1763  if(!ProjName.isEmpty())
1764  readProjectFiles(); // re-read the content ListView
1765 }
1766 
1767 
1768 // --------------------------------------------------------------
1770 {
1771  statusBar()->message(tr("Saving all files..."));
1772  editText->setHidden(true); // disable text edit of component property
1773  DocumentTab->blockSignals(true); // no user interaction during the time
1774 
1775  int No=0;
1776  QucsDoc *Doc; // search, if page is already loaded
1777  while((Doc=getDoc(No++)) != 0) {
1778  if(Doc->DocName.isEmpty()) // make document the current ?
1779  DocumentTab->setCurrentPage(No-1);
1780  saveFile(Doc);
1781  }
1782 
1783  DocumentTab->blockSignals(false);
1784  // Call update() to update subcircuit symbols in current Schematic document.
1785  // TextDoc has no viewport, it needs no update.
1786  QString tabType = DocumentTab->currentWidget()->className();
1787  if (tabType == "Schematic") {
1788  ((Q3ScrollView*)DocumentTab->currentPage())->viewport()->update();
1789  }
1790  view->drawn = false;
1791  statusBar()->message(tr("Ready."));
1792 
1793  // refresh the schematic file path
1794  this->updateSchNameHash();
1795  this->updateSpiceNameHash();
1796 }
1797 
1798 // --------------------------------------------------------------
1799 // Close the currently active file tab
1801 {
1802  // Using file index -1 closes the currently active file window
1803  closeFile(-1);
1804 }
1805 
1806 // --------------------------------------------------------------
1807 // Close the file tab specified by its index
1808 void QucsApp::slotFileClose(int index)
1809 {
1810  // Call closeFile with a specific tab index
1811  closeFile(index);
1812 }
1813 
1814 // --------------------------------------------------------------
1815 // Common function to close a file tab specified by its index
1816 // checking for changes in the file before doing so. If called
1817 // index == -1, the active document will be closed
1818 void QucsApp::closeFile(int index)
1819 {
1820  statusBar()->message(tr("Closing file..."));
1821  editText->setHidden(true); // disable text edit of component property
1822 
1823  QucsDoc *Doc = getDoc(index);
1824  if(Doc->DocChanged) {
1825  switch(QMessageBox::warning(this,tr("Closing Qucs document"),
1826  tr("The document contains unsaved changes!\n")+
1827  tr("Do you want to save the changes before closing?"),
1828  tr("&Save"), tr("&Discard"), tr("Cancel"), 0, 2)) {
1829  case 0 : slotFileSave();
1830  break;
1831  case 2 : return;
1832  }
1833  }
1834 
1835  delete Doc;
1836 
1837  if(DocumentTab->count() < 1) // if no document left, create an untitled
1838  new Schematic(this, "");
1839 
1840  statusBar()->message(tr("Ready."));
1841 }
1842 
1843 
1844 // --------------------------------------------------------------
1846 {
1847  SaveDialog *sd = new SaveDialog(this);
1848  sd->setApp(this);
1849  for(int i=0; i < DocumentTab->count(); ++i) {
1850  QucsDoc *doc = getDoc(i);
1851  if(doc->DocChanged)
1852  sd->addUnsavedDoc(doc);
1853  }
1854  int Result = SaveDialog::DontSave;
1855  if(!sd->isEmpty())
1856  Result = sd->exec();
1857  delete sd;
1858  if(Result == SaveDialog::AbortClosing)
1859  return false;
1860  QucsDoc *doc = 0;
1861  while((doc = getDoc()) != 0)
1862  delete doc;
1863 
1864 
1865  switchEditMode(true); // set schematic edit mode
1866  return true;
1867 }
1868 
1869 
1871 {
1872  statusBar()->message(tr("Open examples directory..."));
1873  QString path = QDir::toNativeSeparators(QucsSettings.ExamplesDir);
1874  QDesktopServices::openUrl(QUrl("file:///" + path.replace("\\","/")));
1875  statusBar()->message(tr("Ready."));
1876 }
1877 
1879 {
1880  QString path = QDir::toNativeSeparators(QucsSettings.DocDir);
1881  QUrl url = QUrl("file:///" + path.replace("\\","/") + "tutorial/" + QObject::sender()->objectName());
1882  QDesktopServices::openUrl(url);
1883 }
1884 
1886 {
1887  QString path = QDir::toNativeSeparators(QucsSettings.DocDir);
1888  QUrl url = QUrl("file:///" + path.replace("\\","/") + "technical/" + QObject::sender()->objectName());
1889  QDesktopServices::openUrl(url);
1890 }
1891 
1893 {
1894  QString path = QDir::toNativeSeparators(QucsSettings.DocDir);
1895  QUrl url = QUrl("file:///" + path.replace("\\","/") + "report/" + QObject::sender()->objectName());
1896  QDesktopServices::openUrl(url);
1897 }
1898 
1899 
1900 
1901 // --------------------------------------------------------------
1902 // Is called when another document is selected via the TabBar.
1903 void QucsApp::slotChangeView(QWidget *w)
1904 {
1905 
1906  editText->setHidden (true); // disable text edit of component property
1907  QucsDoc * Doc;
1908  if(w==NULL)return;
1909  // for text documents
1910  if (isTextDocument (w)) {
1911  TextDoc *d = (TextDoc*)w;
1912  Doc = (QucsDoc*)d;
1913  // update menu entries, etc. if neccesary
1914  magAll->setDisabled(true);
1915  if(cursorLeft->isEnabled())
1916  switchSchematicDoc (false);
1917  }
1918  // for schematic documents
1919  else {
1920  Schematic *d = (Schematic*)w;
1921  Doc = (QucsDoc*)d;
1922  magAll->setDisabled(false);
1923  // already in schematic?
1924  if(cursorLeft->isEnabled()) {
1925  // which mode: schematic or symbol editor ?
1926  if((CompChoose->count() > 1) == d->symbolMode)
1928  }
1929  else {
1930  switchSchematicDoc(true);
1932  }
1933  }
1934 
1935  Doc->becomeCurrent(true);
1936  view->drawn = false;
1937 
1938  if(!HierarchyHistory.isEmpty())
1939  if(*(HierarchyHistory.getLast()) != "*") {
1940  HierarchyHistory.clear(); // no subcircuit history anymore
1941  popH->setEnabled(false);
1942  }
1943 }
1944 
1945 // --------------------------------------------------------------
1946 // Changes to the next document in the TabBar.
1948 {
1949  int No = DocumentTab->currentPageIndex() + 1;
1950  if(No >= DocumentTab->count())
1951  No = 0;
1952 
1953  // make new document the current (calls "slotChangeView(int)" indirectly)
1954  DocumentTab->setCurrentPage(No);
1955  view->drawn = false;
1956 }
1957 
1958 // --------------------------------------------------------------
1960 {
1961  editText->setHidden (true); // disable text edit of component property
1962 
1963  QWidget * w = DocumentTab->currentPage ();
1964  if (isTextDocument (w)) {
1965  QucsDoc * Doc = (QucsDoc *) ((TextDoc *) w);
1966  QString ext = Doc->fileSuffix ();
1967  // Octave properties
1968  if (ext == "m" || ext == "oct") {
1969  }
1970  // Verilog-A properties
1971  else if (ext == "va") {
1972  VASettingsDialog * d = new VASettingsDialog ((TextDoc *) w);
1973  d->exec ();
1974  }
1975  // VHDL and Verilog-HDL properties
1976  else {
1977  DigiSettingsDialog * d = new DigiSettingsDialog ((TextDoc *) w);
1978  d->exec ();
1979  }
1980  }
1981  // schematic properties
1982  else {
1983  SettingsDialog * d = new SettingsDialog ((Schematic *) w);
1984  d->exec ();
1985  }
1986  view->drawn = false;
1987 }
1988 
1989 // --------------------------------------------------------------
1991 {
1992  editText->setHidden(true); // disable text edit of component property
1993 
1994  QucsSettingsDialog *d = new QucsSettingsDialog(this);
1995  d->exec();
1996  view->drawn = false;
1997 }
1998 
1999 
2000 // --------------------------------------------------------------
2002 {
2003  this->updateSchNameHash();
2004  this->updateSpiceNameHash();
2005 
2006  QMessageBox msgBox;
2007  msgBox.setText("The schematic file path has been refreshed.");
2008  msgBox.exec();
2009 }
2010 
2011 
2012 // --------------------------------------------------------------
2013 void QucsApp::updatePortNumber(QucsDoc *currDoc, int No)
2014 {
2015  if(No<0) return;
2016 
2017  QString pathName = currDoc->DocName;
2018  QString ext = currDoc->fileSuffix ();
2019  QFileInfo Info (pathName);
2020  QString Model, File, Name = Info.fileName();
2021 
2022  if (ext == "sch") {
2023  Model = "Sub";
2024 
2025  // enter new port number into ListView
2026  // TODO I'm not sure if I do things correctly here -> RECHECK!!!
2027  QTreeWidgetItem *p;
2028  //for(p = ConSchematics->firstChild(); p!=0; p = p->nextSibling()) {
2029  for(int i=0; i<ConSchematics->childCount(); i++) {
2030  p = ConSchematics->child(i);
2031  if(p->text(0) == Name) {
2032  if(No == 0) p->setText(1,"");
2033  else p->setText(1,QString::number(No)+tr("-port"));
2034  break;
2035  }
2036  }
2037  }
2038  else if (ext == "vhdl" || ext == "vhd") {
2039  Model = "VHDL";
2040  }
2041  else if (ext == "v") {
2042  Model = "Verilog";
2043  }
2044 
2045  // update all occurencies of subcircuit in all open documents
2046  No = 0;
2047  QWidget *w;
2048  Component *pc_tmp;
2049  while((w=DocumentTab->page(No++)) != 0) {
2050  if(isTextDocument (w)) continue;
2051 
2052  // start from the last to omit re-appended components
2053  Schematic *Doc = (Schematic*)w;
2054  for(Component *pc=Doc->Components->last(); pc!=0; ) {
2055  if(pc->Model == Model) {
2056  File = pc->Props.getFirst()->Value;
2057  if((File == pathName) || (File == Name)) {
2058  pc_tmp = Doc->Components->prev();
2059  Doc->recreateComponent(pc); // delete and re-append component
2060  if(!pc_tmp) break;
2061  Doc->Components->findRef(pc_tmp);
2062  pc = Doc->Components->current();
2063  continue;
2064  }
2065  }
2066  pc = Doc->Components->prev();
2067  }
2068  }
2069 }
2070 
2071 
2072 // --------------------------------------------------------------
2073 // TODO -> in case of textdocument, cast to QPlainTextEdit & print
2074 void QucsApp::printCurrentDocument(bool fitToPage)
2075 {
2076  statusBar()->message(tr("Printing..."));
2077  editText->setHidden(true); // disable text edit of component property
2078 
2079  if(isTextDocument (DocumentTab->currentPage())) {
2080  QWidget *w;
2081  w = DocumentTab->currentPage();
2082  QPlainTextEdit *temp = (QPlainTextEdit*)w;
2083 
2084  QPrintDialog *dialog = new QPrintDialog(Printer, this);
2085  dialog->setWindowTitle(tr("Print Document"));
2086  dialog->addEnabledOption(QAbstractPrintDialog::PrintSelection);
2087  if (dialog->exec() == QDialog::Accepted)
2088  temp->print(Printer);
2089 
2090  }
2091  //Printer->setOrientation(QPrinter::Portrait);
2092  else {
2093  Printer->setOrientation(QPrinter::Landscape);
2094 
2095  //Printer->setPrintRange(QPrinter::AllPages);
2096 
2097  if(Printer->setup(this)) { // printer dialog
2098 
2099  QPainter Painter(Printer);
2100  if(!Painter.device()) // valid device available ?
2101  goto Error;
2102 
2103  for(int z=Printer->numCopies(); z>0 ; z--) {
2104  if(Printer->aborted())
2105  break;
2106 
2107  getDoc()->print(Printer, &Painter,
2108  Printer->printRange() == QPrinter::AllPages, fitToPage);
2109  if(z > 1)
2110  if(!Printer->newPage())
2111  goto Error;
2112  }
2113  }
2114  }
2115  statusBar()->message(tr("Ready."));
2116  return;
2117 
2118 Error:
2119  statusBar()->message(tr("Printer Error."));
2120 }
2121 
2122 // --------------------------------------------------------------
2124 {
2125  printCurrentDocument(false);
2126 }
2127 
2128 // --------------------------------------------------------------
2129 // Fit printed content to page size.
2131 {
2132  printCurrentDocument(true);
2133 }
2134 
2135 // --------------------------------------------------------------------
2136 // Exits the application.
2138 {
2139  statusBar()->message(tr("Exiting application..."));
2140  editText->setHidden(true); // disable text edit of component property
2141 
2142  int exit = QMessageBox::information(this,
2143  tr("Quit..."), tr("Do you really want to quit?"),
2144  tr("Yes"), tr("No"));
2145 
2146  if(exit == 0)
2147  if(closeAllFiles()) {
2148  emit signalKillEmAll(); // kill all subprocesses
2149  qApp->quit();
2150  }
2151 
2152  statusBar()->message(tr("Ready."));
2153 }
2154 
2155 //-----------------------------------------------------------------
2156 // To get all close events.
2157 void QucsApp::closeEvent(QCloseEvent* Event)
2158 {
2159  qDebug()<<"x"<<pos().x()<<" ,y"<<pos().y();
2160  qDebug()<<"dx"<<size().width()<<" ,dy"<<size().height();
2161  QucsSettings.x=pos().x();
2162  QucsSettings.y=pos().y();
2163  QucsSettings.dx=size().width();
2164  QucsSettings.dy=size().height();
2165  saveApplSettings(this);
2166 
2167  if(closeAllFiles()) {
2168  emit signalKillEmAll(); // kill all subprocesses
2169  Event->accept();
2170  qApp->quit();
2171  }
2172  else
2173  Event->ignore();
2174 }
2175 
2176 // --------------------------------------------------------------------
2178 {
2179  statusBar()->message(tr("Cutting selection..."));
2180 
2181  Schematic *Doc = (Schematic*)DocumentTab->currentPage();
2182  if(isTextDocument (Doc)) {
2183  ((TextDoc*)Doc)->viewport()->setFocus();
2184  ((TextDoc*)Doc)->cut();
2185  return;
2186  }
2187 
2188  editText->setHidden(true); // disable text edit of component property
2189  QClipboard *cb = QApplication::clipboard(); // get system clipboard
2190 
2191  QString s = Doc->copySelected(true);
2192  if(!s.isEmpty()) {
2193  cb->setText(s, QClipboard::Clipboard);
2194  Doc->viewport()->update();
2195  }
2196 
2197  statusBar()->message(tr("Ready."));
2198 }
2199 
2200 // --------------------------------------------------------------------
2202 {
2203  statusBar()->message(tr("Copying selection to clipboard..."));
2204 
2205  Schematic *Doc = (Schematic*)DocumentTab->currentPage();
2206  if(isTextDocument (Doc)) {
2207  ((TextDoc*)Doc)->viewport()->setFocus();
2208  ((TextDoc*)Doc)->copy();
2209  return;
2210  }
2211 
2212  editText->setHidden(true); // disable text edit of component property
2213  QClipboard *cb = QApplication::clipboard(); // get system clipboard
2214 
2215  QString s = Doc->copySelected(false);
2216  if(!s.isEmpty())
2217  cb->setText(s, QClipboard::Clipboard);
2218 
2219  statusBar()->message(tr("Ready."));
2220 }
2221 
2222 // --------------------------------------------------------------------
2223 // Is called when the toolbar button is pressed to go into a subcircuit.
2225 {
2226  editText->setHidden(true); // disable text edit of component property
2227 
2228  Schematic *Doc = (Schematic*)DocumentTab->currentPage();
2229  Component *pc = Doc->searchSelSubcircuit();
2230  if(pc == 0) return;
2231 
2232  QString *ps = new QString("*");
2233  HierarchyHistory.append(ps); // sign not to clear HierarchyHistory
2234 
2235  QString s = pc->getSubcircuitFile();
2236  if(!gotoPage(s)) {
2237  HierarchyHistory.remove();
2238  return;
2239  }
2240 
2241  *(HierarchyHistory.getLast()) = Doc->DocName; // remember for the way back
2242  popH->setEnabled(true);
2243 }
2244 
2245 // --------------------------------------------------------------------
2246 // Is called when the toolbar button is pressed to leave a subcircuit.
2248 {
2249  editText->setHidden(true); // disable text edit of component property
2250 
2251  if(HierarchyHistory.count() == 0) return;
2252 
2253  QString Doc = *(HierarchyHistory.getLast());
2254  *(HierarchyHistory.last()) = "*"; // sign not to clear HierarchyHistory
2255 
2256  if(!gotoPage(Doc)) {
2257  *(HierarchyHistory.getLast()) = Doc;
2258  return;
2259  }
2260 
2261  HierarchyHistory.remove();
2262  if(HierarchyHistory.count() == 0)
2263  popH->setEnabled(false);
2264 }
2265 
2266 // --------------------------------------------------------------
2268 {
2269  editText->setHidden(true); // disable text edit of component property
2270  getDoc()->showAll();
2271 }
2272 
2273 // -----------------------------------------------------------
2274 // Sets the scale factor to 1.
2276 {
2277  editText->setHidden(true); // disable text edit of component property
2278  getDoc()->showNoZoom();
2279 }
2280 
2281 // -----------------------------------------------------------
2283 {
2284  editText->setHidden(true); // disable text edit of component property
2285  getDoc()->zoomBy(0.5f);
2286 }
2287 
2288 
2294 {
2295  editText->setHidden(true); // disable text edit of component property
2296 
2297  QucsDoc *Doc;
2298  QWidget *w = DocumentTab->currentPage();
2299  if(isTextDocument (w)) {
2300  Doc = (QucsDoc*)((TextDoc*)w);
2301  if(Doc->SimTime.isEmpty() && ((TextDoc*)Doc)->simulation) {
2303  if(d->exec() == QDialog::Rejected)
2304  return;
2305  }
2306  }
2307  else
2308  Doc = (QucsDoc*)((Schematic*)w);
2309 
2310  if(Doc->DocName.isEmpty()) // if document 'untitled' ...
2311  if(!saveAs()) return; // ... save schematic before
2312 
2313  // Perhaps the document was modified from another program ?
2314  QFileInfo Info(Doc->DocName);
2315  if(Doc->lastSaved.isValid()) {
2316  if(Doc->lastSaved < Info.lastModified()) {
2317  int No = QMessageBox::warning(this, tr("Warning"),
2318  tr("The document was modified by another program !") + '\n' +
2319  tr("Do you want to reload or keep this version ?"),
2320  tr("Reload"), tr("Keep it"));
2321  if(No == 0)
2322  Doc->load();
2323  }
2324  }
2325 
2327 
2328  if(Info.extension(false) == "m" || Info.extension(false) == "oct") {
2329  // It is an Octave script.
2330  if(Doc->DocChanged)
2331  Doc->save();
2332  slotViewOctaveDock(true);
2334  return;
2335  }
2336 
2337  SimMessage *sim = new SimMessage(w, this);
2338  // disconnect is automatically performed, if one of the involved objects
2339  // is destroyed !
2340  connect(sim, SIGNAL(SimulationEnded(int, SimMessage*)), this,
2341  SLOT(slotAfterSimulation(int, SimMessage*)));
2342  connect(sim, SIGNAL(displayDataPage(QString&, QString&)),
2343  this, SLOT(slotChangePage(QString&, QString&)));
2344 
2345  sim->show();
2346  if(!sim->startProcess()) return;
2347 
2348  // to kill it before qucs ends
2349  connect(this, SIGNAL(signalKillEmAll()), sim, SLOT(slotClose()));
2350 }
2351 
2352 // ------------------------------------------------------------------------
2353 // Is called after the simulation process terminates.
2355 {
2356  if(Status != 0) return; // errors ocurred ?
2357 
2358  if(sim->ErrText->document()->lineCount() > 1) // were there warnings ?
2359  slotShowWarnings();
2360 
2361  int i=0;
2362  QWidget *w; // search, if page is still open
2363  while((w=DocumentTab->page(i++)) != 0)
2364  if(w == sim->DocWidget)
2365  break;
2366 
2367  if(sim->showBias == 0) { // paint dc bias into schematic ?
2368  sim->slotClose(); // close and delete simulation window
2369  if(w) { // schematic still open ?
2370  SweepDialog *Dia = new SweepDialog((Schematic*)sim->DocWidget);
2371  }
2372  }
2373  else {
2374  if(sim->SimRunScript) {
2375  // run script
2376  octave->startOctave();
2377  octave->runOctaveScript(sim->Script);
2378  }
2379  if(sim->SimOpenDpl) {
2380  // switch to data display
2381  if(sim->DataDisplay.right(2) == ".m" ||
2382  sim->DataDisplay.right(4) == ".oct") { // Is it an Octave script?
2383  octave->startOctave();
2385  }
2386  else
2387  slotChangePage(sim->DocName, sim->DataDisplay);
2388  sim->slotClose(); // close and delete simulation window
2389  }
2390  else
2391  if(w) if(!isTextDocument (sim->DocWidget))
2392  // load recent simulation data (if document is still open)
2393  ((Schematic*)sim->DocWidget)->reloadGraphs();
2394  }
2395 
2396  if(!isTextDocument (sim->DocWidget))
2397  ((Schematic*)sim->DocWidget)->viewport()->update();
2398 
2399  // put all dataset files into "Content"-ListView (update)
2400 /* QStringList Elements = ProjDir.entryList("*.dat", QDir::Files, QDir::Name);
2401  for(it = Elements.begin(); it != Elements.end(); ++it)
2402  new QListViewItem(ConDatasets, (*it).ascii());*/
2403 }
2404 
2405 // ------------------------------------------------------------------------
2407 {
2408  getDoc()->showBias = 0;
2409  slotSimulate();
2410 }
2411 
2412 // ------------------------------------------------------------------------
2413 // Changes to the corresponding data display page or vice versa.
2414 void QucsApp::slotChangePage(QString& DocName, QString& DataDisplay)
2415 {
2416  if(DataDisplay.isEmpty()) return;
2417 
2418  QFileInfo Info(DocName);
2419  QString Name = Info.dirPath() + QDir::separator() + DataDisplay;
2420 
2421  QWidget *w = DocumentTab->currentPage();
2422 
2423  int z = 0; // search, if page is already loaded
2424  QucsDoc * d = findDoc (Name, &z);
2425 
2426  if(d)
2427  DocumentTab->setCurrentPage(z);
2428  else { // no open page found ?
2429  QString ext = QucsDoc::fileSuffix (DataDisplay);
2430  if (ext != "vhd" && ext != "vhdl" && ext != "v" && ext != "va" &&
2431  ext != "oct" && ext != "m")
2432  d = new Schematic (this, Name);
2433  else
2434  d = new TextDoc (this, Name);
2435 
2436  QFile file(Name);
2437  if(file.open(QIODevice::ReadOnly)) { // try to load document
2438  file.close();
2439  if(!d->load()) {
2440  delete d;
2441  view->drawn = false;
2442  return;
2443  }
2444  }
2445  else {
2446  if(file.open(QIODevice::ReadWrite)) { // if document doesn't exist, create
2447  //TODO RECHECK!! new Q3ListViewItem(ConDisplays, DataDisplay); // add new name
2448  QTreeWidgetItem *temp = new QTreeWidgetItem(ConDisplays);
2449  temp->setText(0,DataDisplay);
2450  d->DataDisplay = Info.fileName();
2451  }
2452  else {
2453  QMessageBox::critical(this, tr("Error"), tr("Cannot create ")+Name);
2454  return;
2455  }
2456  file.close();
2457  }
2458 
2459  d->becomeCurrent(true);
2460  }
2461 
2462 
2463  if(DocumentTab->currentPage() == w) // if page not ...
2464  if(!isTextDocument (w))
2465  ((Schematic*)w)->reloadGraphs(); // ... changes, reload here !
2466 
2467  TabView->setCurrentPage (2); // switch to "Component"-Tab
2468  if (Name.right(4) == ".dpl") {
2469  int i = Category::getModulesNr (QObject::tr("diagrams"));
2470  CompChoose->setCurrentItem (i); // switch to diagrams
2471  slotSetCompView (i);
2472  }
2473 }
2474 
2475 // -------------------------------------------------------------------
2476 // Changes to the data display of current page.
2478 {
2479  QucsDoc *d = getDoc();
2480  if(d->DataDisplay.isEmpty()) {
2481  QMessageBox::critical(this, tr("Error"), tr("No page set !"));
2482  return;
2483  }
2484 
2485  if(d->DocName.right(2) == ".m" ||
2486  d->DocName.right(4) == ".oct")
2487  slotViewOctaveDock(true);
2488  else
2490 }
2491 
2492 // -------------------------------------------------------------------
2493 // Is called when a double-click is made in the content ListView.
2494 void QucsApp::slotOpenContent(QTreeWidgetItem *item)
2495 {
2496  editText->setHidden(true); // disable text edit of component property
2497 
2498  if(item == 0) return; // no item was double clicked
2499  if(item->parent() == 0) return; // no document, but item "schematic", ...
2500 
2501 /*
2502  QucsSettings.QucsWorkDir.setPath(QucsSettings.QucsHomeDir.path());
2503  QString p = ProjName+"_prj";
2504  if(!QucsSettings.QucsWorkDir.cd(p)) {
2505  QMessageBox::critical(this, tr("Error"),
2506  tr("Cannot access project directory: ")+
2507  QucsSettings.QucsWorkDir.path()+QDir::separator()+p);
2508  return;
2509  }*/
2510 
2511  QFileInfo Info(QucsSettings.QucsWorkDir.filePath(item->text(0)));
2512  QString Suffix = Info.extension(false);
2513 
2514  if (Suffix == "sch" || Suffix == "dpl" || Suffix == "vhdl" ||
2515  Suffix == "vhd" || Suffix == "v" || Suffix == "va" ||
2516  Suffix == "m" || Suffix == "oct") {
2517  gotoPage(Info.absFilePath());
2518  updateRecentFilesList(Info.absFilePath());
2520 
2521  if(item->text(1).isEmpty()) // is subcircuit ?
2522  if(Suffix == "sch") return;
2523 
2524  select->blockSignals(true); // switch on the 'select' action ...
2525  select->setOn(true);
2526  select->blockSignals(false);
2527 
2528  activeAction = select;
2529  MouseMoveAction = 0;
2533  return;
2534  }
2535 
2536  if(Suffix == "dat") {
2537  editFile(Info.absFilePath()); // open datasets with text editor
2538  return;
2539  }
2540 
2541 
2542  // File is no Qucs file, so go through list and search a user
2543  // defined program to open it.
2544  QStringList com;
2545  QStringList::Iterator it = QucsSettings.FileTypes.begin();
2546  while(it != QucsSettings.FileTypes.end()) {
2547  if(Suffix == (*it).section('/',0,0)) {
2548  com = QStringList::split(" ", (*it).section('/',1,1));
2549  com << Info.absFilePath();
2550  QProcess *Program = new QProcess();
2551  //Program->setCommunication(0);
2552  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2553  env.insert("PATH", env.value("PATH") );
2554  Program->setProcessEnvironment(env);
2555  Program->start(com.join(" "));
2556  if(Program->state()!=QProcess::Running&&
2557  Program->state()!=QProcess::Starting) {
2558  QMessageBox::critical(this, tr("Error"),
2559  tr("Cannot start \"%1\"!").arg(Info.absFilePath()));
2560  delete Program;
2561  }
2562  return;
2563  }
2564  it++;
2565  }
2566 
2567  // If no appropriate program was found, open as text file.
2568  editFile(Info.absFilePath()); // open datasets with text editor
2569 }
2570 
2571 // ---------------------------------------------------------
2572 // Is called when the mouse is clicked within the Content QListView.
2573 void QucsApp::slotSelectSubcircuit(QTreeWidgetItem *item)
2574 {
2575  editText->setHidden(true); // disable text edit of component property
2576 
2577  if(item == 0) { // mouse button pressed not over an item ?
2578  Content->clearSelection(); // deselect component in ListView
2579  return;
2580  }
2581 
2582 
2583  bool isVHDL = false;
2584  bool isVerilog = false;
2585  if(item->parent() == 0) return;
2586  if(item->parent()->text(0) == tr("Schematics")) {
2587  if(item->text(1).isEmpty())
2588  return; // return, if not a subcircuit
2589  }
2590  else if(item->parent()->text(0) == tr("VHDL"))
2591  isVHDL = true;
2592  else if(item->parent()->text(0) == tr("Verilog"))
2593  isVerilog = true;
2594  else
2595  return;
2596 
2597  // delete previously selected elements
2598  if(view->selElem != 0) delete view->selElem;
2599  view->selElem = 0;
2600 
2601  // toggle last toolbar button off
2602  if(activeAction) {
2603  activeAction->blockSignals(true); // do not call toggle slot
2604  activeAction->setOn(false); // set last toolbar button off
2605  activeAction->blockSignals(false);
2606  }
2607  activeAction = 0;
2608 
2609  Component *Comp;
2610  if(isVHDL)
2611  Comp = new VHDL_File();
2612  else if(isVerilog)
2613  Comp = new Verilog_File();
2614  else
2615  Comp = new Subcircuit();
2616  Comp->Props.first()->Value = item->text(0);
2617  Comp->recreate(0);
2618  view->selElem = Comp;
2619 
2620  if(view->drawn)
2621  ((Q3ScrollView*)DocumentTab->currentPage())->viewport()->update();
2622  view->drawn = false;
2625  MouseReleaseAction = 0;
2627 }
2628 
2629 
2630 // ---------------------------------------------------------
2631 // Is called when the mouse is clicked within the Content QListView.
2632 void QucsApp::slotSelectLibComponent(QTreeWidgetItem *item)
2633 {
2634  // get the current document
2635  Schematic *Doc = (Schematic*)DocumentTab->currentPage();
2636 
2637  // if the current document is a schematic activate the paste
2638  if(!Doc->inherits("QPlainTextEdit"))
2639  {
2640 
2641  if(item == 0)
2642  {
2643  // mouse button pressed not over an item ?
2644  Content->clearSelection(); // deselect component in ListView
2645  return;
2646  }
2647 
2648  // if theres not a higher level item, this is a top level item,
2649  // not a component item so return
2650  if(item->parent() == 0) return;
2651 
2652  if(item->text(1).isEmpty()) return; // return, if not a subcircuit
2653 
2654  // copy the subcircuit schematic to the clipboard
2655  QClipboard *cb = QApplication::clipboard();
2656  cb->setText(item->text(1));
2657 
2658  // activate the paste command
2659  slotEditPaste (true);
2660  }
2661 
2662 }
2663 
2664 
2665 // ---------------------------------------------------------
2666 // This function is called if the document type changes, i.e.
2667 // from schematic to text document or vice versa.
2668 void QucsApp::switchSchematicDoc (bool SchematicMode)
2669 {
2670  // switch our scroll key actions on/off according to SchematicMode
2671  cursorLeft->setEnabled(SchematicMode);
2672  cursorRight->setEnabled(SchematicMode);
2673  cursorUp->setEnabled(SchematicMode);
2674  cursorDown->setEnabled(SchematicMode);
2675 
2676  // text document
2677  if (!SchematicMode) {
2678  if (activeAction) {
2679  activeAction->blockSignals (true); // do not call toggle slot
2680  activeAction->setOn (false); // set last toolbar button off
2681  activeAction->blockSignals (false);
2682  }
2683  activeAction = select;
2684  select->blockSignals (true);
2685  select->setOn (true);
2686  select->blockSignals (false);
2687  }
2688  // schematic document
2689  else {
2690  MouseMoveAction = 0;
2694  }
2695 
2696  selectMarker->setEnabled (SchematicMode);
2697  alignTop->setEnabled (SchematicMode);
2698  alignBottom->setEnabled (SchematicMode);
2699  alignLeft->setEnabled (SchematicMode);
2700  alignRight->setEnabled (SchematicMode);
2701  centerHor->setEnabled (SchematicMode);
2702  centerVert->setEnabled (SchematicMode);
2703  distrHor->setEnabled (SchematicMode);
2704  distrVert->setEnabled (SchematicMode);
2705  onGrid->setEnabled (SchematicMode);
2706  moveText->setEnabled (SchematicMode);
2707  filePrintFit->setEnabled (SchematicMode);
2708  editRotate->setEnabled (SchematicMode);
2709  editMirror->setEnabled (SchematicMode);
2710  editMirrorY->setEnabled (SchematicMode);
2711  intoH->setEnabled (SchematicMode);
2712  popH->setEnabled (SchematicMode);
2713  dcbias->setEnabled (SchematicMode);
2714  insWire->setEnabled (SchematicMode);
2715  insLabel->setEnabled (SchematicMode);
2716  insPort->setEnabled (SchematicMode);
2717  insGround->setEnabled (SchematicMode);
2718  insEquation->setEnabled (SchematicMode);
2719  setMarker->setEnabled (SchematicMode);
2720 
2721  exportAsImage->setEnabled (SchematicMode); // only export schematic, no text
2722 
2723  editFind->setEnabled (!SchematicMode);
2724  editFindAgain->setEnabled (!SchematicMode);
2725  insEntity->setEnabled (!SchematicMode);
2726 
2727  buildModule->setEnabled(!SchematicMode); // only build if VA document
2728 }
2729 
2730 // ---------------------------------------------------------
2731 void QucsApp::switchEditMode(bool SchematicMode)
2732 {
2733  fillComboBox(SchematicMode);
2734  slotSetCompView(0);
2735 
2736  intoH->setEnabled(SchematicMode);
2737  popH->setEnabled(SchematicMode);
2738  editActivate->setEnabled(SchematicMode);
2739  changeProps->setEnabled(SchematicMode);
2740  insEquation->setEnabled(SchematicMode);
2741  insGround->setEnabled(SchematicMode);
2742  insPort->setEnabled(SchematicMode);
2743  insWire->setEnabled(SchematicMode);
2744  insLabel->setEnabled(SchematicMode);
2745  setMarker->setEnabled(SchematicMode);
2746  selectMarker->setEnabled(SchematicMode);
2747  simulate->setEnabled(SchematicMode);
2748 }
2749 
2750 // ---------------------------------------------------------
2752 {
2753  if(Doc->symbolMode) {
2754  // go into select modus to avoid placing a forbidden element
2755  select->setOn(true);
2756 
2757  switchEditMode(false);
2758  }
2759  else
2760  switchEditMode(true);
2761 }
2762 
2763 // ---------------------------------------------------------
2764 bool QucsApp::isTextDocument(QWidget *w) {
2765  if (w->inherits("QPlainTextEdit"))
2766  return true;
2767  return false;
2768 }
2769 
2770 // ---------------------------------------------------------
2771 // Is called if the "symEdit" action is activated, i.e. if the user
2772 // switches between the two painting mode: Schematic and (subcircuit)
2773 // symbol.
2775 {
2776  QWidget *w = DocumentTab->currentPage();
2777 
2778  // in a text document (e.g. VHDL)
2779  if (isTextDocument (w)) {
2780  TextDoc *TDoc = (TextDoc*)w;
2781  // set 'DataDisplay' document of text file to symbol file
2782  QFileInfo Info(TDoc->DocName);
2783  QString sym = Info.baseName(true)+".sym";
2784  TDoc->DataDisplay = sym;
2785 
2786  // symbol file already loaded?
2787  int paint_mode = 0;
2788  if (!findDoc (QucsSettings.QucsWorkDir.filePath(sym)))
2789  paint_mode = 1;
2790 
2791  // change current page to appropriate symbol file
2792  slotChangePage(TDoc->DocName,TDoc->DataDisplay);
2793 
2794  // set 'DataDisplay' document of symbol file to original text file
2795  Schematic *SDoc = (Schematic*)DocumentTab->currentPage();
2796  SDoc->DataDisplay = Info.fileName();
2797 
2798  // change into symbol mode
2799  if (paint_mode) // but only switch coordinates if newly loaded
2800  SDoc->switchPaintMode();
2801  SDoc->symbolMode = true;
2803  SDoc->becomeCurrent(true);
2804  SDoc->viewport()->update();
2805  view->drawn = false;
2806  }
2807  // in a normal schematic, data display or symbol file
2808  else {
2809  Schematic *SDoc = (Schematic*)w;
2810  // in a symbol file
2811  if(SDoc->DocName.right(4) == ".sym") {
2812  slotChangePage(SDoc->DocName, SDoc->DataDisplay);
2813  }
2814  // in a normal schematic
2815  else {
2816  editText->setHidden(true); // disable text edit of component property
2817  SDoc->switchPaintMode(); // twist the view coordinates
2819  SDoc->becomeCurrent(true);
2820  SDoc->viewport()->update();
2821  view->drawn = false;
2822  }
2823  }
2824 }
2825 
2826 // -----------------------------------------------------------
2828 {
2829  if(!view->focusElement) return;
2830  if(view->focusElement->Type != isMarker) return;
2831  Marker *pm = (Marker*)view->focusElement;
2832 
2833 // double Z0 = 50.0;
2834  QString Var = pm->pGraph->Var;
2835  double Imag = pm->VarPos[pm->nVarPos+1];
2836  if(Var == "Sopt") // noise matching ?
2837  Imag *= -1.0;
2838 
2839  MatchDialog *Dia = new MatchDialog(this);
2840  Dia->TwoCheck->setChecked(false);
2841  Dia->TwoCheck->setEnabled(false);
2842 // Dia->Ref1Edit->setText(QString::number(Z0));
2843  Dia->S11magEdit->setText(QString::number(pm->VarPos[pm->nVarPos]));
2844  Dia->S11degEdit->setText(QString::number(Imag));
2845  Dia->setFrequency(pm->VarPos[0]);
2846 
2847  slotToPage();
2848  if(Dia->exec() != QDialog::Accepted)
2849  return;
2850 }
2851 
2852 // -----------------------------------------------------------
2854 {
2855  if(!view->focusElement) return;
2856  if(view->focusElement->Type != isMarker) return;
2857  Marker *pm = (Marker*)view->focusElement;
2858 
2859  QString DataSet;
2860  Schematic *Doc = (Schematic*)DocumentTab->currentPage();
2861  int z = pm->pGraph->Var.find(':');
2862  if(z <= 0) DataSet = Doc->DataSet;
2863  else DataSet = pm->pGraph->Var.mid(z+1);
2864  double Freq = pm->VarPos[0];
2865 
2866  QFileInfo Info(Doc->DocName);
2867  DataSet = Info.dirPath()+QDir::separator()+DataSet;
2868 
2869  Diagram *Diag = new Diagram();
2870 
2871  Graph *pg = new Graph("S[1,1]");
2872  Diag->Graphs.append(pg);
2873  if(!Diag->loadVarData(DataSet, pg)) {
2874  QMessageBox::critical(0, tr("Error"), tr("Could not load S[1,1]."));
2875  return;
2876  }
2877 
2878  pg = new Graph("S[1,2]");
2879  Diag->Graphs.append(pg);
2880  if(!Diag->loadVarData(DataSet, pg)) {
2881  QMessageBox::critical(0, tr("Error"), tr("Could not load S[1,2]."));
2882  return;
2883  }
2884 
2885  pg = new Graph("S[2,1]");
2886  Diag->Graphs.append(pg);
2887  if(!Diag->loadVarData(DataSet, pg)) {
2888  QMessageBox::critical(0, tr("Error"), tr("Could not load S[2,1]."));
2889  return;
2890  }
2891 
2892  pg = new Graph("S[2,2]");
2893  Diag->Graphs.append(pg);
2894  if(!Diag->loadVarData(DataSet, pg)) {
2895  QMessageBox::critical(0, tr("Error"), tr("Could not load S[2,2]."));
2896  return;
2897  }
2898 
2899  DataX *Data = Diag->Graphs.getFirst()->cPointsX.first();
2900  if(Data->Var != "frequency") {
2901  QMessageBox::critical(0, tr("Error"), tr("Wrong dependency!"));
2902  return;
2903  }
2904 
2905  double *Value = Data->Points;
2906  // search for values for chosen frequency
2907  for(z=0; z<Data->count; z++)
2908  if(*(Value++) == Freq) break;
2909 
2910  // get S-parameters
2911  double S11real = *(Diag->Graphs.first()->cPointsY + 2*z);
2912  double S11imag = *(Diag->Graphs.current()->cPointsY + 2*z + 1);
2913  double S12real = *(Diag->Graphs.next()->cPointsY + 2*z);
2914  double S12imag = *(Diag->Graphs.current()->cPointsY + 2*z + 1);
2915  double S21real = *(Diag->Graphs.next()->cPointsY + 2*z);
2916  double S21imag = *(Diag->Graphs.current()->cPointsY + 2*z + 1);
2917  double S22real = *(Diag->Graphs.next()->cPointsY + 2*z);
2918  double S22imag = *(Diag->Graphs.current()->cPointsY + 2*z + 1);
2919 
2920  delete Diag;
2921 
2922  MatchDialog *Dia = new MatchDialog(this);
2923  Dia->TwoCheck->setEnabled(false);
2924  Dia->setFrequency(Freq);
2925  Dia->S11magEdit->setText(QString::number(S11real));
2926  Dia->S11degEdit->setText(QString::number(S11imag));
2927  Dia->S12magEdit->setText(QString::number(S12real));
2928  Dia->S12degEdit->setText(QString::number(S12imag));
2929  Dia->S21magEdit->setText(QString::number(S21real));
2930  Dia->S21degEdit->setText(QString::number(S21imag));
2931  Dia->S22magEdit->setText(QString::number(S22real));
2932  Dia->S22degEdit->setText(QString::number(S22imag));
2933 
2934  slotToPage();
2935  if(Dia->exec() != QDialog::Accepted)
2936  return;
2937 }
2938 
2939 // -----------------------------------------------------------
2940 // Is called if the "edit" action is clicked on right mouse button menu.
2942 {
2943  if(view->focusMEvent)
2944  view->editElement((Schematic*)DocumentTab->currentPage(), view->focusMEvent);
2945 }
2946 
2947 // -----------------------------------------------------------
2948 // Hides the edit for component property. Called e.g. if QLineEdit
2949 // looses the focus.
2951 {
2952  editText->setHidden(true);
2953 }
2954 
2955 // -----------------------------------------------------------
2956 // Searches the qucs path list for all schematic files and creates
2957 // a hash for lookup later
2959 {
2960  // update the list of paths to search in qucsPathList, this
2961  // removes nonexisting entries
2962  updatePathList();
2963 
2964  // now go through the paths creating a map to all the schematic files
2965  // found in the directories. Note that we go through the list of paths from
2966  // first index to last index. Since keys are unique it means schematic files
2967  // in directories at the end of the list take precendence over those at the
2968  // start of the list, we should warn about shadowing of schematic files in
2969  // this way in the future
2970  QStringList nameFilter;
2971  nameFilter << "*.sch";
2972 
2973  // clear out any existing hash table entriess
2974  schNameHash.clear();
2975 
2976  foreach (QString qucspath, qucsPathList) {
2977  QDir thispath(qucspath);
2978  // get all the schematic files in the directory
2979  QFileInfoList schfilesList = thispath.entryInfoList( nameFilter, QDir::Files );
2980  // put each one in the hash table with the unique key the base name of
2981  // the file, note this will overwrite the value if the key already exists
2982  foreach (QFileInfo schfile, schfilesList) {
2983  QString bn = schfile.completeBaseName();
2984  schNameHash[schfile.completeBaseName()] = schfile.absoluteFilePath();
2985  }
2986  }
2987 
2988  // finally check the home/working directory
2989  QDir thispath(QucsSettings.QucsWorkDir);
2990  QFileInfoList schfilesList = thispath.entryInfoList( nameFilter, QDir::Files );
2991  // put each one in the hash table with the unique key the base name of
2992  // the file, note this will overwrite the value if the key already exists
2993  foreach (QFileInfo schfile, schfilesList) {
2994  schNameHash[schfile.completeBaseName()] = schfile.absoluteFilePath();
2995  }
2996 }
2997 
2998 // --------------------------------------------------------
2999 // Produces a name filter suitible for file dialogs from the
3000 // list of recognised spice extensions
3002 {
3003  QString spexts = " (";
3004 
3005  for (int i = 0; i < spiceExtensions.count (); i++)
3006  {
3007  spexts += "*" + spiceExtensions[i] + " ";
3008  }
3009 
3010  spexts += ");;";
3011 
3012  return spexts;
3013 }
3014 
3015 // -----------------------------------------------------------
3016 // Searches the qucs path list for all spice files and creates
3017 // a hash for lookup later
3019 {
3020  // update the list of paths to search in qucsPathList, this
3021  // removes nonexisting entries
3022  updatePathList();
3023 
3024  // now go through the paths creating a map to all the spice files
3025  // found in the directories. Note that we go through the list of paths from
3026  // first index to last index. Since keys are unique it means spice files
3027  // in directories at the end of the list take precendence over those at the
3028  // start of the list, we should warn about shadowing of spice files in
3029  // this way in the future
3030 
3031  // clear out any existing hash table entriess
3032  spiceNameHash.clear();
3033 
3034  foreach (QString qucspath, qucsPathList) {
3035  QDir thispath(qucspath);
3036  // get all the schematic files in the directory
3037  QFileInfoList spicefilesList = thispath.entryInfoList( spiceExtensions, QDir::Files );
3038  // put each one in the hash table with the unique key the base name of
3039  // the file, note this will overwrite the value if the key already exists
3040  foreach (QFileInfo spicefile, spicefilesList) {
3041  QString bn = spicefile.completeBaseName();
3042  schNameHash[spicefile.completeBaseName()] = spicefile.absoluteFilePath();
3043  }
3044  }
3045 
3046  // finally check the home/working directory
3047  QDir thispath(QucsSettings.QucsWorkDir);
3048  QFileInfoList spicefilesList = thispath.entryInfoList( spiceExtensions, QDir::Files );
3049  // put each one in the hash table with the unique key the base name of
3050  // the file, note this will overwrite the value if the key already exists
3051  foreach (QFileInfo spicefile, spicefilesList) {
3052  spiceNameHash[spicefile.completeBaseName()] = spicefile.absoluteFilePath();
3053  }
3054 }
3055 
3056 // -----------------------------------------------------------
3057 // update the list of paths, pruning non-existing paths
3059 {
3060  // check each path actually exists, if not remove it
3061  QMutableListIterator<QString> i(qucsPathList);
3062  while (i.hasNext()) {
3063  i.next();
3064  QDir thispath(i.value());
3065  if (!thispath.exists())
3066  {
3067  // the path does not exist, remove it from the list
3068  i.remove();
3069  }
3070  }
3071 }
3072 
3073 // replace the old path list with a new one
3074 void QucsApp::updatePathList(QStringList newPathList)
3075 {
3076  // clear out the old path list
3077  qucsPathList.clear();
3078 
3079  // copy the new path into the path list
3080  foreach(QString path, newPathList)
3081  {
3082  qucsPathList.append(path);
3083  }
3084  // do the normal path update operations
3085  updatePathList();
3086 }
3087 
3088 
3090 {
3091  QSettings* settings = new QSettings("qucs","qucs");
3093  if (!QucsSettings.RecentDocs.contains(s)) {
3094  QucsSettings.RecentDocs.append(s);
3095  } else {
3096  QucsSettings.RecentDocs.remove(s);
3097  QucsSettings.RecentDocs.append(s);
3098  }
3099  if (QucsSettings.RecentDocs.count()>8) {
3100  QucsSettings.RecentDocs.removeFirst();
3101  }
3102 
3103  settings->setValue("RecentDocs",QucsSettings.RecentDocs.join("*"));
3104  delete settings;
3105 }
3106 
3108 {
3110 }
3111 
3113 {
3114  Schematic *sch = (Schematic*)DocumentTab->currentPage();
3115 
3116  const int bourder = 30;
3117 
3118  int w,h,wsel,hsel,
3119  xmin, ymin, xmin_sel, ymin_sel;
3120 
3121  sch->getSchWidthAndHeight(w, h, xmin, ymin);
3122  sch->getSelAreaWidthAndHeight(wsel, hsel, xmin_sel, ymin_sel);
3123  w += bourder;
3124  h += bourder;
3125  wsel += bourder;
3126  hsel += bourder;
3127 
3128  bool noselect;
3129  if ((wsel==(bourder+1))&&(hsel==(bourder+1))) noselect = true;
3130  else noselect = false;
3131 
3132  ExportDialog* dlg = new ExportDialog(w,h,wsel,hsel,lastExportFilename,noselect,this);
3133 
3134  if (diagram) dlg->setDiagram();
3135 
3136  if (dlg->exec()) {
3137 
3138  QString filename = dlg->FileToSave();
3139  lastExportFilename = filename;
3140 
3141  bool exportAll;
3142  if (dlg->isExportSelected()) {
3143  exportAll = false;
3144  w=wsel;
3145  h=hsel;
3146  xmin = xmin_sel;
3147  ymin = ymin_sel;
3148  } else {
3149  exportAll = true;
3150  }
3151 
3152  float scal;
3153  if (!dlg->isOriginalSize()) {
3154  scal = (float) dlg->Xpixels()/w;
3155  w = round(w*scal);
3156  h = round(h*scal);
3157  } else {
3158  scal = 1.0;
3159  }
3160 
3161  if (dlg->isValidFilename()) {
3162  if (!dlg->isSvg()) {
3163 
3164  QImage* img;
3165 
3166  switch (dlg->getImgFormat()) {
3167  case ExportDialog::Coloured : img = new QImage(w,h,QImage::Format_RGB888);
3168  break;
3169  case ExportDialog::Monochrome : img = new QImage(w,h,QImage::Format_Mono);
3170  break;
3171  default : break;
3172  }
3173 
3174  QPainter* p = new QPainter(img);
3175  p->fillRect(0,0,w,h,Qt::white);
3176  ViewPainter* vp = new ViewPainter(p);
3177  vp->init(p,scal,0,0,xmin*scal-bourder/2,ymin*scal-bourder/2,scal,scal);
3178 
3179  sch->paintSchToViewpainter(vp,exportAll,true);
3180 
3181  img->save(filename);
3182 
3183  delete vp;
3184  delete p;
3185  delete img;
3186  } else {
3187  QSvgGenerator* svg1 = new QSvgGenerator();
3188  svg1->setResolution(this->physicalDpiX());
3189 
3190  if (dlg->needsInkscape()) {
3191  svg1->setFileName(filename+".tmp.svg");
3192  } else {
3193  svg1->setFileName(filename);
3194  }
3195 
3196  //svg1->setSize(QSize(1.12*w,1.1*h));
3197  svg1->setSize(QSize(1.12*w,h));
3198  QPainter *p = new QPainter(svg1);
3199  p->fillRect(0,0,svg1->size().width(),svg1->size().height(),Qt::white);
3200  ViewPainter *vp = new ViewPainter(p);
3201  vp->init(p,1.0,0,0,xmin-bourder/2,ymin-bourder/2,1.0,1.0);
3202 
3203  sch->paintSchToViewpainter(vp,exportAll,true);
3204 
3205  delete vp;
3206  delete p;
3207  delete svg1;
3208 
3209  if (dlg->needsInkscape()) {
3210  QString cmd = "inkscape -z -D --file=";
3211  cmd += filename+".tmp.svg ";
3212 
3213  if (dlg->isPdf_Tex()) {
3214  QString tmp = filename;
3215  tmp.chop(4);
3216  cmd = cmd + "--export-pdf="+ tmp + " --export-latex";
3217  }
3218 
3219  if (dlg->isPdf()) {
3220  cmd = cmd + "--export-pdf=" + filename;
3221  }
3222 
3223  if (dlg->isEps()) {
3224  cmd = cmd + "--export-eps=" + filename;
3225  }
3226 
3227  int result = QProcess::execute(cmd);
3228 
3229  if (result!=0) {
3230  QMessageBox* msg = new QMessageBox(QMessageBox::Critical,tr("Export to image"),
3231  tr("Inkscape start error!"),
3232  QMessageBox::Ok);
3233  msg->exec();
3234  delete msg;
3235  }
3236  QFile::remove(filename+".tmp.svg");
3237  }
3238  }
3239 
3240  successExportMessages(QFile::exists(filename));
3241 
3242  } else {
3243  QMessageBox* msg = new QMessageBox(QMessageBox::Critical,tr("Export to image"),
3244  tr("Unsupported format of graphics file. \n"
3245  "Use PNG, JPEG or SVG graphics!"),
3246  QMessageBox::Ok);
3247  msg->exec();
3248  delete msg;
3249  }
3250 
3251 
3252  }
3253 
3254 }
3255 
3256 
3257 
3259 {
3260  if (ok) {
3261  QMessageBox* msg = new QMessageBox(QMessageBox::Information,tr("Export to image"),
3262  tr("Sucessfully exported!"),
3263  QMessageBox::Ok);
3264  msg->exec();
3265  delete msg;
3266  } else {
3267  QMessageBox* msg = new QMessageBox(QMessageBox::Critical,tr("Export to image"),
3268  tr("Disk write error!"),
3269  QMessageBox::Ok);
3270  msg->exec();
3271  delete msg;
3272  }
3273 }
void slotResizePropEdit(const QString &)
void slotHelpReport()
Definition: qucs.cpp:1892
MessageDock * messageDock
Definition: qucs.h:192
Element *(* pInfoVAFunc)(QString &, QString &, bool, QString)
Definition: module.h:27
void setApp(QucsApp *a)
Definition: savedialog.cpp:45
void slotShowOne()
Definition: qucs.cpp:2275
void slotZoomOut()
Definition: qucs.cpp:2282
void slotCMenuOpen()
Definition: qucs.cpp:861
QAction * alignTop
Definition: qucs.h:292
void slotProjOpenButt()
Definition: qucs.cpp:1354
void closeFile(int)
Definition: qucs.cpp:1818
void readProjectFiles()
Definition: qucs.cpp:1222
void slotDCbias()
Definition: qucs.cpp:2406
static QString pathName(QString longpath)
Definition: simmessage.cpp:312
void MPressElement(Schematic *, QMouseEvent *, float, float)
void slotMenuOpenProject()
Definition: qucs.cpp:1336
SearchDialog * SearchDia
Definition: qucs.h:82
QDir QucsWorkDir
Definition: main.h:65
void initToolBar()
Definition: qucs_init.cpp:877
QTreeWidgetItem * ConDatasets
Definition: qucs.h:196
int Type
Definition: element.h:152
QTreeWidgetItem * ConOthers
Definition: qucs.h:196
QAction * setMarker
Definition: qucs.h:292
double * VarPos
Definition: marker.h:55
void slotPopHierarchy()
Definition: qucs.cpp:2247
void slotShowAll()
Definition: qucs.cpp:2267
void slotProjNewButt()
Definition: qucs.cpp:1136
void updateSpiceNameHash(void)
Definition: qucs.cpp:3018
QAction * centerVert
Definition: qucs.h:292
void slotFilePrintFit()
Definition: qucs.cpp:2130
QAction * ActionCMenuInsert
Definition: qucs.h:172
void slotFilePrint()
Definition: qucs.cpp:2123
Definition of the TextDoc class.
void slotFileClose()
Definition: qucs.cpp:1800
QString fileType(const QString &)
Definition: qucs.cpp:1003
bool gotoPage(const QString &)
Definition: qucs.cpp:1527
QComboBox * CompChoose
Definition: qucs.h:200
void slotHelpTechnical()
Definition: qucs.cpp:1885
int count
Definition: graph.h:53
void(MouseActions::* MouseMoveAction)(Schematic *, QMouseEvent *)
Definition: qucs.h:85
QLineEdit * S12magEdit
Definition: matchdialog.h:52
void slotApplSettings()
Definition: qucs.cpp:1990
QTextEdit * ErrText
Definition: simmessage.h:89
QString DocName
Definition: simmessage.h:86
QCheckBox * OpenProj
Definition: newprojdialog.h:40
void slotCallLibrary()
void MMoveElement(Schematic *, QMouseEvent *)
bool deleteProject(const QString &, const QString &)
Definition: qucs.cpp:1430
QAction * magAll
Definition: qucs.h:174
bool startOctave()
Definition: graph.h:57
QAction * centerHor
Definition: qucs.h:292
void editElement(Schematic *, QMouseEvent *)
void switchPaintMode()
Definition: schematic.cpp:1822
void slotFileSaveAs()
Definition: qucs.cpp:1743
tQucsSettings QucsSettings
Definition: main.cpp:52
void slotSelectSubcircuit(QTreeWidgetItem *)
Definition: qucs.cpp:2573
void(MouseActions::* MousePressAction)(Schematic *, QMouseEvent *, float, float)
Definition: qucs.h:86
QTreeWidgetItem * ConOctave
Definition: qucs.h:196
~QucsApp()
Definition: qucs.cpp:181
void slotFileSettings()
Definition: qucs.cpp:1959
int showBias
Definition: qucsdoc.h:63
void slotFileSave()
Definition: qucs.cpp:1611
QAction * ActionCMenuOpen
Definition: qucs.h:172
QShortcut * cursorDown
Definition: qucs.h:278
bool needsInkscape()
Definition: marker.h:31
void becomeCurrent(bool)
Definition: schematic.cpp:197
The MessageDock class definiion.
void signalKillEmAll()
QAction * ActionCMenuCopy
Definition: qucs.h:172
QString Var
Definition: graph.h:50
QShortcut * cursorUp
Definition: qucs.h:278
void slotCMenuInsert()
Definition: qucs.cpp:1097
QTreeWidgetItem * ConVerilog
Definition: qucs.h:196
void slotChangeView(QWidget *)
Definition: qucs.cpp:1903
QAction * alignLeft
Definition: qucs.h:292
bool checkVersion(QString &Line)
Definition: main.cpp:602
static void registerModules(void)
Definition: module.cpp:223
QAction * editFind
Definition: qucs.h:292
bool isEmpty() const
Definition: savedialog.cpp:130
virtual bool load()
Definition: qucsdoc.h:38
static QString fileSuffix(const QString &)
Definition: qucsdoc.cpp:102
void switchEditMode(bool)
Definition: qucs.cpp:2731
QString fileSuffix(void)
Definition: qucsdoc.cpp:107
void slotToPage()
Definition: qucs.cpp:2477
void changeSchematicSymbolMode(Schematic *)
Definition: qucs.cpp:2751
Element *(* pInfoFunc)(QString &, char *&, bool)
Definition: module.h:26
static void unregisterModules(void)
Definition: module.cpp:438
static QStringList getCategories(void)
Definition: module.cpp:463
Definition: graph.h:47
QString Script
Definition: simmessage.h:86
Element * focusElement
Definition: mouseactions.h:51
void fillLibrariesTreeView(void)
Definition: qucs.cpp:404
QucsApp()
Definition: qucs.cpp:95
QAction * insEntity
Definition: qucs.h:292
void slotSymbolEdit()
Definition: qucs.cpp:2774
int dy
Definition: main.h:45
QString FileToSave()
bool deleteDirectoryContent(QDir &Dir)
Definition: qucs.cpp:1397
QString ProjName
Definition: qucs.h:74
virtual void print(QPrinter *, QPainter *, bool, bool)
Definition: qucsdoc.h:40
void updatePortNumber(QucsDoc *, int)
Definition: qucs.cpp:2013
QucsDoc * getDoc(int No=-1)
Definition: qucs.cpp:562
QLineEdit * S21degEdit
Definition: matchdialog.h:52
static int getModulesNr(QString)
Definition: module.cpp:488
int showBias
Definition: simmessage.h:83
QStringList qucsPathList
Definition: main.cpp:56
bool DocChanged
Definition: qucsdoc.h:60
QucsDoc * findDoc(QString, int *Pos=0)
Definition: qucs.cpp:582
unsigned int numRecentDocs
Definition: main.h:74
QLineEdit * editText
Definition: qucs.h:81
pInfoFunc info
Definition: module.h:50
QString Var
Definition: graph.h:75
QAction * editRotate
Definition: qucs.h:292
QAction * insEquation
Definition: qucs.h:292
Definitions and declarations for the main application.
QAction * insWire
Definition: qucs.h:292
void slotRefreshSchPath()
Definition: qucs.cpp:2001
QString ExamplesDir
Definition: main.h:61
void slotFileOpen()
Definition: qucs.cpp:1567
void initCursorMenu()
Definition: qucs.cpp:791
const char * empty_xpm[]
Definition: qucsdoc.cpp:65
QTreeWidgetItem * ConVerilogA
Definition: qucs.h:196
void slotCMenuRename()
Definition: qucs.cpp:939
void slotShowContentMenu(const QPoint &)
Definition: qucs.cpp:829
Q3PtrList< QString > HierarchyHistory
Definition: qucs.h:203
void slotIntoHierarchy()
Definition: qucs.cpp:2224
void slotProjDelButt()
Definition: qucs.cpp:1484
QShortcut * cursorRight
Definition: qucs.h:278
bool SimOpenDpl
Definition: simmessage.h:84
virtual void becomeCurrent(bool)
Definition: qucsdoc.h:41
ExportDialog::ImgFormat getImgFormat()
QStringList spiceExtensions
Definition: qucs.h:77
Q3PtrList< Component > * Components
Definition: schematic.h:123
void MReleaseSelect(Schematic *, QMouseEvent *)
QAction * insGround
Definition: qucs.h:292
Q3PtrList< Property > Props
Definition: component.h:72
QAction * filePrintFit
Definition: qucs.h:174
void slotFileExamples()
Definition: qucs.cpp:1870
void slotEditPaste(bool)
void switchSchematicDoc(bool)
Definition: qucs.cpp:2668
void slotSimulate()
QucsApp::slotSimulate is called when the simulate toolbar button is pressed.
Definition: qucs.cpp:2293
QAction * dcbias
Definition: qucs.h:174
bool symbolMode
Definition: schematic.h:128
QAction * intoH
Definition: qucs.h:174
virtual void showNoZoom()
Definition: qucsdoc.h:44
void slotHelpTutorial()
Definition: qucs.cpp:1878
Definition: module.h:30
QAction * alignRight
Definition: qucs.h:292
void printCurrentDocument(bool)
Definition: qucs.cpp:2074
QTreeWidgetItem * ConDisplays
Definition: qucs.h:196
void runOctaveScript(const QString &)
void successExportMessages(bool ok)
Definition: qucs.cpp:3258
Element * selElem
Definition: mouseactions.h:50
QAction * insLabel
Definition: qucs.h:292
void slotEditElement()
Definition: qucs.cpp:2941
void slot2PortMatching()
Definition: qucs.cpp:2853
QAction * moveText
Definition: qucs.h:292
int loadVarData(const QString &, Graph *)
Definition: diagram.cpp:828
Q3PtrList< Graph > Graphs
Definition: diagram.h:95
QHash< QString, QString > spiceNameHash
Definition: qucs.h:79
bool saveApplSettings(QucsApp *qucs)
Definition: main.cpp:127
QString lastDirOpenSave
Definition: qucs.cpp:1564
QString DocDir
Definition: main.h:62
void initActions()
QucsApp::initActions Initializes all QActions of the application.
Definition: qucs_init.cpp:32
void initStatusBar()
Definition: qucs_init.cpp:932
void slotMenuDelProject()
Definition: qucs.cpp:1461
QListWidget * CompComps
Definition: qucs.h:165
bool saveAs()
Definition: qucs.cpp:1632
static Q3PtrList< Module > getModules(QString)
Definition: module.cpp:475
MouseActions * view
Definition: qucs.h:163
void slotOpenContent(QTreeWidgetItem *)
Definition: qucs.cpp:2494
QAction * editMirrorY
Definition: qucs.h:292
QDateTime lastSaved
Definition: qucsdoc.h:56
void initMenuBar()
Definition: qucs_init.cpp:659
QLineEdit * S11degEdit
Definition: matchdialog.h:52
void(MouseActions::* MouseReleaseAction)(Schematic *, QMouseEvent *)
Definition: qucs.h:88
void slotToggleDock(bool)
Definition: qucs_init.cpp:1025
QString copySelected(bool)
Definition: schematic.cpp:1265
static Element * info(QString &, QString &, bool getNewOne=false, QString filename="")
vacomponent::info is used to either get information or create objects.
void slotSelectLibComponent(QTreeWidgetItem *)
Definition: qucs.cpp:2632
Definition: element.h:48
void slotMenuCloseProject()
Definition: qucs.cpp:1373
virtual void showAll()
Definition: qucsdoc.h:43
void initContentListView()
Definition: qucs.cpp:193
virtual int save()
Definition: qucsdoc.h:39
void initView()
QucsApp::initView Setup the layour of all widgets.
Definition: qucs.cpp:220
QAction * viewBrowseDock
Definition: qucs.h:264
int nVarPos
Definition: marker.h:54
QMenu * ContentMenu
Definition: qucs.h:169
QAction * editActivate
Definition: qucs.h:292
QTreeWidget * libTreeWidget
Definition: qucs.h:166
QDockWidget * octDock
Definition: qucs.h:190
QPrinter * Printer
Definition: qucs.h:185
virtual QString getSubcircuitFile()
Definition: component.h:63
bool IgnoreFutureVersion
Definition: main.h:77
QStringList RecentDocs
Definition: main.h:75
QDir QucsHomeDir
Definition: main.h:66
QString SimTime
Definition: qucsdoc.h:55
void getSelAreaWidthAndHeight(int &wsel, int &hsel, int &xmin_sel_, int &ymin_sel_)
Definition: schematic.cpp:2221
void slotApplyCompText()
virtual float zoomBy(float)
Definition: qucsdoc.h:42
void slotHideEdit()
Definition: qucs.cpp:2950
int y
Definition: main.h:45
static QMap< QString, QString > vaComponents
Definition: module.h:43
void updateRecentFilesList(QString s)
Definition: qucs.cpp:3089
QString fileBase(void)
Definition: qucsdoc.cpp:116
void paintSchToViewpainter(ViewPainter *p, bool printAll, bool toImage, int screenDpiX=96, int printerDpiX=300)
Definition: schematic.cpp:657
QString QucsFileFilter
Definition: qucs.h:204
QString getSpiceFileFilter(void)
Definition: qucs.cpp:3001
void slotCMenuDelete()
Definition: qucs.cpp:975
QCheckBox * TwoCheck
Definition: matchdialog.h:55
void slotCMenuCopy()
Definition: qucs.cpp:870
void slotResetWarnings()
Definition: qucs_init.cpp:970
QTreeWidgetItem * ConSchematics
Definition: qucs.h:196
void slotCMenuDelGroup()
Definition: qucs.cpp:1030
QAction * popH
Definition: qucs.h:174
void fillComboBox(bool)
Definition: qucs.cpp:601
bool saveFile(QucsDoc *Doc=0)
Definition: qucs.cpp:1595
QTabWidget * DocumentTab
Definition: qucs.h:164
bool isOriginalSize()
void slotPowerMatching()
Definition: qucs.cpp:2827
void openProject(const QString &, const QString &)
Definition: qucs.cpp:1302
QAction * activeAction
Definition: qucs.h:182
QWidget * DocWidget
Definition: simmessage.h:82
QAction * select
Definition: qucs.h:292
QLineEdit * ProjName
Definition: newprojdialog.h:39
bool startProcess()
Definition: simmessage.cpp:131
void slotFileNew()
Definition: qucs.cpp:1504
QAction * exportAsImage
Definition: qucs.h:180
QAction * distrHor
Definition: qucs.h:292
bool isTextDocument(QWidget *)
Definition: qucs.cpp:2764
QLineEdit * S22degEdit
Definition: matchdialog.h:52
Component * searchSelSubcircuit()
void adjustDirectory()
void slotEditCut()
Definition: qucs.cpp:2177
QAction * changeProps
Definition: qucs.h:292
bool closeAllFiles()
Definition: qucs.cpp:1845
bool isValidFilename()
bool isExportSelected()
QAction * ActionCMenuDelete
Definition: qucs.h:172
void slotSaveSchematicToGraphicsFile(bool diagram=false)
Definition: qucs.cpp:3112
QDockWidget * dock
Definition: qucs.h:188
void slotAfterSimulation(int, SimMessage *)
Definition: qucs.cpp:2354
void slotViewOctaveDock(bool)
Definition: qucs_init.cpp:1034
void setFrequency(double)
QLineEdit * S21magEdit
Definition: matchdialog.h:52
QShortcut * cursorLeft
Definition: qucs.h:278
void addUnsavedDoc(QucsDoc *doc)
Definition: savedialog.cpp:90
void slotChangePage(QString &, QString &)
Definition: qucs.cpp:2414
void editFile(const QString &)
void slotUpdateRecentFiles()
QString DocName
Definition: qucsdoc.h:51
virtual void setName(const QString &)
Definition: qucsdoc.h:37
void slotFileQuit()
Definition: qucs.cpp:2137
void slotClose()
Definition: simmessage.cpp:734
void(MouseActions::* MouseDoubleClickAction)(Schematic *, QMouseEvent *)
Definition: qucs.h:87
The TextDoc class definition.
Definition: textdoc.h:49
QAction * onGrid
Definition: qucs.h:292
QAction * ActionCMenuRename
Definition: qucs.h:172
void readProjects()
Definition: qucs.cpp:1107
void slotEditCopy()
Definition: qucs.cpp:2201
void slotSetCompView(int)
Definition: qucs.cpp:619
QAction * distrVert
Definition: qucs.h:292
void init(QPainter *, float, int, int, int, int, float FontScale_=0.0, float PrintScale_=1.0)
Definition: viewpainter.cpp:36
QListWidget * Projects
Definition: qucs.h:194
QAction * buildModule
Definition: qucs.h:292
QLineEdit * S11magEdit
Definition: matchdialog.h:52
double * Points
Definition: graph.h:52
QAction * simulate
Definition: qucs.h:174
void recreateComponent(Component *)
QAction * alignBottom
Definition: qucs.h:292
QString lastExportFilename
Definition: qucs.h:373
void MDoubleClickSelect(Schematic *, QMouseEvent *)
QAction * viewStatusBar
Definition: qucs.h:264
QTreeWidget * Content
Definition: qucs.h:195
QTabWidget * TabView
Definition: qucs.h:189
friend class SaveDialog
Definition: qucs.h:372
QMouseEvent * focusMEvent
Definition: mouseactions.h:52
int dx
Definition: main.h:45
QLineEdit * S22magEdit
Definition: matchdialog.h:52
QAction * selectMarker
Definition: qucs.h:292
OctaveWindow * octave
Definition: qucs.h:191
QColor BGColor
Definition: main.h:48
void updatePathList(void)
Definition: qucs.cpp:3058
void MPressSelect(Schematic *, QMouseEvent *, float, float)
QString LibDir
Definition: main.h:59
void getSchWidthAndHeight(int &w, int &h, int &xmin_, int &ymin_)
Definition: schematic.cpp:2155
QStringList FileTypes
Definition: main.h:72
QString DataDisplay
Definition: qucsdoc.h:53
bool SimRunScript
Definition: simmessage.h:85
QAction * insPort
Definition: qucs.h:292
QString DataDisplay
Definition: simmessage.h:86
void updateSchNameHash(void)
Definition: qucs.cpp:2958
virtual void recreate(Schematic *)
Definition: component.h:39
void slotToggleOctave(bool)
Definition: qucs_init.cpp:1045
void slotSelectComponent(QListWidgetItem *)
Definition: qucs.cpp:713
QLineEdit * S12degEdit
Definition: matchdialog.h:52
QTreeWidgetItem * ConSources
Definition: qucs.h:196
QHash< QString, QString > schNameHash
Definition: qucs.h:76
void slotTextNew()
Definition: qucs.cpp:1515
QAction * viewToolBar
Definition: qucs.h:264
void slotFileSaveAll()
Definition: qucs.cpp:1769
#define isMarker
Definition: element.h:117
void slotNextTab()
Definition: qucs.cpp:1947
void slotShowWarnings()
Definition: qucs_init.cpp:946
int x
Definition: main.h:45
Graph * pGraph
Definition: marker.h:52
static int testFile(const QString &)
Definition: qucs.cpp:1156
void closeEvent(QCloseEvent *)
Definition: qucs.cpp:2157
QAction * editFindAgain
Definition: qucs.h:292
void slotSaveDiagramToGraphicsFile()
Definition: qucs.cpp:3107
QAction * editMirror
Definition: qucs.h:292
void slotOpenProject(QListWidgetItem *)
Definition: qucs.cpp:1366