My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
qucslib.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qucslib.cpp
3  -------------
4  begin : Sat May 28 2005
5  copyright : (C) 2005 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 
22 #include <qmenubar.h>
23 #include <qaction.h>
24 #include <qpopupmenu.h>
25 #include <qcombobox.h>
26 #include <qclipboard.h>
27 #include <qapplication.h>
28 #include <qlayout.h>
29 #include <qhbox.h>
30 #include <qvgroupbox.h>
31 #include <qpushbutton.h>
32 #include <qmessagebox.h>
33 #include <qtextedit.h>
34 #include <qlistbox.h>
35 #include <qregexp.h>
36 
37 #include "qucslib.h"
38 #include "librarydialog.h"
39 #include "displaydialog.h"
40 #include "symbolwidget.h"
41 #include "searchdialog.h"
42 
43 
44 /* Constructor setups the GUI. */
46 {
47  // set application icon
48  setIcon (QPixmap(QucsSettings.BitmapDir + "big.qucs.xpm"));
49  setCaption("Qucs Library Tool " PACKAGE_VERSION);
50 
51  QMenuBar * menuBar = new QMenuBar (this);
52 
53  // create file menu
54  QPopupMenu * fileMenu = new QPopupMenu ();
55  QAction * manageLib =
56  new QAction ("Manage User Libraries...", tr("Manage User &Libraries..."), CTRL+Key_M, this);
57  manageLib->addTo (fileMenu);
58  connect(manageLib, SIGNAL(activated()), SLOT(slotManageLib()));
59 
60  fileMenu->insertSeparator();
61 
62  QAction * fileQuit =
63  new QAction ("Quit", tr("&Quit"), CTRL+Key_Q, this);
64  fileQuit->addTo (fileMenu);
65  connect(fileQuit, SIGNAL(activated()), SLOT(slotQuit()));
66 
67  // create help menu
68  QPopupMenu * helpMenu = new QPopupMenu ();
69  QAction * helpHelp =
70  new QAction (tr("Help"), tr("&Help"), Key_F1, this);
71  helpHelp->addTo (helpMenu);
72  connect(helpHelp, SIGNAL(activated()), SLOT(slotHelp()));
73  QAction * helpAbout =
74  new QAction (tr("About"), tr("About"), 0, helpMenu);
75  helpAbout->addTo (helpMenu);
76  connect(helpAbout, SIGNAL(activated()), SLOT(slotAbout()));
77 
78  // setup menu bar
79  menuBar->insertItem (tr("&File"), fileMenu);
80  menuBar->insertSeparator ();
81  menuBar->insertItem (tr("&Help"), helpMenu);
82 
83  // main box
84  QVBoxLayout * all = new QVBoxLayout (this);
85  all->setSpacing (0);
86  all->setMargin (0);
87 
88  // reserve space for menubar
89  QWidget * Space = new QWidget (this);
90  Space->setFixedSize(5, menuBar->height() + 2);
91  all->addWidget (Space);
92 
93  // main layout
94  QHBox * h = new QHBox (this);
95  h->setSpacing (5);
96  h->setMargin (3);
97  all->addWidget (h);
98 
99  // library and component choice
100  QVGroupBox * LibGroup = new QVGroupBox (tr("Component Selection"), h);
101  Library = new QComboBox (LibGroup);
102  connect(Library, SIGNAL(activated(int)), SLOT(slotSelectLibrary(int)));
103  CompList = new QListBox(LibGroup);
104  connect(CompList, SIGNAL(highlighted(QListBoxItem*)),
105  SLOT(slotShowComponent(QListBoxItem*)));
106 
107  QHBox * h1 = new QHBox (LibGroup);
108  QPushButton * SearchButton = new QPushButton (tr("Search..."), h1);
109  connect(SearchButton, SIGNAL(clicked()), SLOT(slotSearchComponent()));
110  h1->setStretchFactor(new QWidget(h1), 5); // stretchable placeholder
111 
112 
113  // component display
114  QVGroupBox *CompGroup = new QVGroupBox (tr("Component"), h);
115  CompDescr = new QTextEdit(CompGroup);
116  CompDescr->setTextFormat(Qt::PlainText);
117  CompDescr->setReadOnly(true);
118  CompDescr->setWordWrap(QTextEdit::NoWrap);
119 
120  Symbol = new SymbolWidget (CompGroup);
121 
122  QHBox * h2 = new QHBox (CompGroup);
123  QPushButton * CopyButton = new QPushButton (tr("Copy to clipboard"), h2);
124  connect(CopyButton, SIGNAL(clicked()), SLOT(slotCopyToClipBoard()));
125  QPushButton * ShowButton = new QPushButton (tr("Show Model"), h2);
126  connect(ShowButton, SIGNAL(clicked()), SLOT(slotShowModel()));
127 
128  // ......................................................
129  putLibrariesIntoCombobox();
130 }
131 
132 /* Destructor destroys the application. */
134 {
135 }
136 
137 // ----------------------------------------------------
138 // Put all available libraries into ComboBox.
139 void QucsLib::putLibrariesIntoCombobox()
140 {
141  Library->clear();
142 
143  UserLibCount = 0;
144  QStringList LibFiles;
145  QStringList::iterator it;
146  if(UserLibDir.cd(".")) { // user library directory exists ?
147  LibFiles = UserLibDir.entryList("*.lib", QDir::Files, QDir::Name);
148  UserLibCount = LibFiles.count();
149 
150  for(it = LibFiles.begin(); it != LibFiles.end(); it++)
151  Library->insertItem((*it).left((*it).length()-4));
152  }
153 
154  QDir LibDir(QucsSettings.LibDir);
155  LibFiles = LibDir.entryList("*.lib", QDir::Files, QDir::Name);
156 
157  for(it = LibFiles.begin(); it != LibFiles.end(); it++)
158  Library->insertItem((*it).left((*it).length()-4));
159 
160  slotSelectLibrary(0);
161 }
162 
163 // ----------------------------------------------------
164 void QucsLib::slotAbout()
165 {
166  QMessageBox::about(this, tr("About..."),
167  "QucsLib Version " PACKAGE_VERSION "\n"+
168  tr("Library Manager for Qucs\n")+
169  tr("Copyright (C) 2005 by Michael Margraf\n")+
170  "\nThis is free software; see the source for copying conditions."
171  "\nThere is NO warranty; not even for MERCHANTABILITY or "
172  "\nFITNESS FOR A PARTICULAR PURPOSE.");
173 }
174 
175 // ----------------------------------------------------
176 void QucsLib::slotQuit()
177 {
178  int tmp;
179  tmp = x(); // call size and position function in order to ...
180  tmp = y(); // ... set them correctly before closing the ...
181  tmp = width(); // dialog !!! Otherwise the frame of the window ...
182  tmp = height(); // will not be recognized (a X11 problem).
183 
184  accept();
185 }
186 
187 // ----------------------------------------------------
188 void QucsLib::closeEvent(QCloseEvent *Event)
189 {
190  int tmp;
191  tmp = x(); // call size and position function in order to ...
192  tmp = y(); // ... set them correctly before closing the ...
193  tmp = width(); // dialog !!! Otherwise the frame of the window ...
194  tmp = height(); // will not be recognized (a X11 problem).
195 
196  Event->accept();
197 }
198 
199 // ----------------------------------------------------
200 void QucsLib::slotManageLib()
201 {
202  (new LibraryDialog(this))->exec();
203  putLibrariesIntoCombobox();
204 }
205 
206 // ----------------------------------------------------
207 void QucsLib::slotHelp()
208 {
209  DisplayDialog *d = new DisplayDialog(this);
210  d->setCaption(tr("QucsLib Help"));
211  d->resize(250, 325);
212  d->Text->setText(
213  tr("QucsLib is a program to manage Qucs component libraries. "
214  "On the left side of the application window the available "
215  "libraries can be browsed to find the wanted component. "
216  "By clicking on the component name its description can be "
217  "seen on the right side. The selected component is "
218  "transported to the Qucs application by clicking on the "
219  "button \"Copy to Clipboard\". Being back in the schematic "
220  "window the component can be inserted by pressing CTRL-V "
221  " (paste from clipboard).") + "\n" +
222  tr("A more comfortable way: The component can also be placed "
223  "onto the schematic by using Drag n'Drop."));
224  d->show();
225 }
226 
227 // ----------------------------------------------------
228 void QucsLib::slotCopyToClipBoard()
229 {
230  QString s = "<Qucs Schematic " PACKAGE_VERSION ">\n";
231  s += "<Components>\n " +
232  Symbol->theModel() +
233  "\n</Components>\n";
234 
235  // put resulting schematic into clipboard
236  QClipboard *cb = QApplication::clipboard();
237  cb->setText(s);
238 }
239 
240 // ----------------------------------------------------
241 void QucsLib::slotShowModel()
242 {
243  DisplayDialog *d = new DisplayDialog(this, false);
244  d->setCaption(tr("Model"));
245  d->resize(500, 150);
246  d->Text->setText(Symbol->ModelString);
247  d->Text->setWordWrap(QTextEdit::NoWrap);
248  d->VHDLText->setText(Symbol->VHDLModelString);
249  d->VHDLText->setWordWrap(QTextEdit::NoWrap);
250  d->VerilogText->setText(Symbol->VerilogModelString);
251  d->VerilogText->setWordWrap(QTextEdit::NoWrap);
252  d->show();
253 }
254 
255 // ----------------------------------------------------
256 void QucsLib::slotSelectLibrary(int Index)
257 {
258  int Start, End, NameStart, NameEnd;
259  End = Library->count()-1;
260  if(Library->text(End) == tr("Search result")) {
261  if(Index < End)
262  Library->removeItem(End); // if search result still there -> remove it
263  else return;
264  }
265 
266  CompList->clear();
267  LibraryComps.clear();
268  DefaultSymbol = "";
269 
270  QFile file;
271  if(Index < UserLibCount) // Is it user library ?
272  file.setName(UserLibDir.absPath() + QDir::separator() + Library->text(Index) + ".lib");
273  else
274  file.setName(QucsSettings.LibDir + Library->text(Index) + ".lib");
275 
276  if(!file.open(IO_ReadOnly)) {
277  QMessageBox::critical(this, tr("Error"),
278  tr("Cannot open \"%1\".").arg(
279  QucsSettings.LibDir + Library->text(Index) + ".lib"));
280  return;
281  }
282 
283  QTextStream ReadWhole(&file);
284  QString LibraryString = ReadWhole.read();
285  file.close();
286 
287  Start = LibraryString.find("<Qucs Library ");
288  if(Start < 0) {
289  QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
290  return;
291  }
292  End = LibraryString.find('>', Start);
293  if(End < 0) {
294  QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
295  return;
296  }
297  QString LibName = LibraryString.mid(Start, End-Start).section('"', 1, 1);
298 
299  Start = LibraryString.find("\n<", End);
300  if(Start < 0) return;
301  if(LibraryString.mid(Start+2, 14) == "DefaultSymbol>") {
302  End = LibraryString.find("\n</DefaultSymbol>");
303  if(End < 0) {
304  QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
305  return;
306  }
307 
308  DefaultSymbol = LibraryString.mid(Start+16, End-Start-16);
309  Start = End + 3;
310  }
311 
312  while((Start=LibraryString.find("\n<Component ", Start)) > 0) {
313  Start++;
314  NameStart = Start + 11;
315  NameEnd = LibraryString.find('>', NameStart);
316  if(NameEnd < 0) continue;
317 
318  End = LibraryString.find("\n</Component>", NameEnd);
319  if(End < 0) continue;
320  End += 13;
321 
322  CompList->insertItem(LibraryString.mid(NameStart, NameEnd-NameStart));
323  LibraryComps.append(LibName+'\n'+LibraryString.mid(Start, End-Start));
324  Start = End;
325  }
326 
327  CompList->setSelected(0, true); // select first item
328 }
329 
330 // ----------------------------------------------------
331 void QucsLib::slotSearchComponent()
332 {
333  SearchDialog *d = new SearchDialog(this);
334  d->setCaption(tr("Search Library Component"));
335  if(d->exec() == QDialog::Accepted)
336  QMessageBox::information(this, tr("Result"),
337  tr("No appropriate component found."));
338 }
339 
340 // ----------------------------------------------------
341 void QucsLib::slotShowComponent(QListBoxItem *Item)
342 {
343  if(!Item) return;
344 
345  QStringList::Iterator CompString = LibraryComps.at(CompList->index(Item));
346  QString LibName = (*CompString).section('\n', 0, 0);
347  CompDescr->setText("Name: " + Item->text());
348  CompDescr->append("Library: " + LibName);
349  CompDescr->append("----------------------------");
350 
351  if(Library->currentItem() < UserLibCount)
352  LibName = UserLibDir.absPath() + QDir::separator() + LibName;
353 
354  QString content;
355  if(!getSection("Description", *CompString, content))
356  return;
357  CompDescr->append(content);
358 
359  if(!getSection("Model", *CompString, content))
360  return;
361  Symbol->ModelString = content;
362  if(Symbol->ModelString.contains('\n') < 2)
363  Symbol->createSymbol(LibName, Item->text());
364 
365  if(!getSection("VHDLModel", *CompString, content))
366  return;
367  Symbol->VHDLModelString = content;
368 
369  if(!getSection("VerilogModel", *CompString, content))
370  return;
371  Symbol->VerilogModelString = content;
372 
373  if(!getSection("Symbol", *CompString, content))
374  return;
375  if(!content.isEmpty())
376  Symbol->setSymbol(content, LibName, Item->text());
377  else if(!DefaultSymbol.isEmpty()) // has library a default symbol ?
378  Symbol->setSymbol(DefaultSymbol, LibName, Item->text());
379 }
380 
381 // ----------------------------------------------------
382 bool QucsLib::getSection(QString section, QString &list, QString &content)
383 {
384  int Start, End;
385  Start = list.find("<"+section+">");
386  content = "";
387  if(Start > 0) {
388  Start += section.length()+2;
389  End = list.find("</"+section+">", Start);
390  if(End < 0) {
391  QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
392  return false;
393  }
394  content = list.mid(Start, End-Start);
395  content.replace(QRegExp("\\n\\x20+"), "\n").remove(0, 1);
396  }
397  return true;
398 }