My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
subcircuit.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  subcircuit.cpp
3  ----------------
4  begin : Sat Aug 23 2003
5  copyright : (C) 2003 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 "subcircuit.h"
23 #include "qucs.h"
24 #include "schematic.h"
25 #include "main.h"
26 
27 #include <qdir.h>
28 #include <qfileinfo.h>
29 #include <qregexp.h>
30 
31 #include <math.h>
32 #include <limits.h>
33 
34 extern QDir QucsWorkDir;
35 
36 
38 {
39  Type = isComponent; // both analog and digital
40  Description = QObject::tr("subcircuit");
41 
42  Props.append(new Property("File", "", false,
43  QObject::tr("name of qucs schematic file")));
44 
45  Model = "Sub";
46  Name = "SUB";
47 
48  // Do NOT call createSymbol() here. But create port to let it rotate.
49  Ports.append(new Port(0, 0, false));
50 }
51 
52 // ---------------------------------------------------------------------
54 {
55  Subcircuit *p = new Subcircuit();
56  p->Props.getFirst()->Value = Props.getFirst()->Value;
57  p->recreate(0);
58  return p;
59 }
60 
61 // -------------------------------------------------------
62 Element* Subcircuit::info(QString& Name, char* &BitmapFile, bool getNewOne)
63 {
64  Name = QObject::tr("Subcircuit");
65  BitmapFile = (char *) "subcircuit";
66 
67  if(getNewOne) {
68  Subcircuit *p = new Subcircuit();
69  p->recreate(0); // createSymbol() is NOT called in constructor !!!
70  return p;
71  }
72  return 0;
73 }
74 
75 // ---------------------------------------------------------------------
76 // Makes the schematic symbol subcircuit with the correct number
77 // of ports.
79 {
80  int No;
81  QString FileName(Props.getFirst()->Value);
82  FileName = getSubcircuitFile();
83 
84  tx = INT_MIN;
85  ty = INT_MIN;
86  if(loadSymbol(FileName) > 0) { // try to load subcircuit symbol
87  if(tx == INT_MIN) tx = x1+4;
88  if(ty == INT_MIN) ty = y2+4;
89  // remove unused ports
90  for(Port *pp = Ports.first(); pp != 0; ) {
91  if(!pp->avail) { Ports.remove(); pp = Ports.current (); }
92  else pp = Ports.next();
93  }
94  }
95  else {
96  No = QucsApp::testFile(FileName);
97  if(No < 0) No = 0;
98 
99  Ports.clear();
100  remakeSymbol(No); // no symbol was found -> create standard symbol
101  }
102 }
103 
104 // ---------------------------------------------------------------------
106 {
107  int h = 30*((No-1)/2) + 15;
108  Lines.append(new Line(-15, -h, 15, -h,QPen(QPen::darkBlue,2)));
109  Lines.append(new Line( 15, -h, 15, h,QPen(QPen::darkBlue,2)));
110  Lines.append(new Line(-15, h, 15, h,QPen(QPen::darkBlue,2)));
111  Lines.append(new Line(-15, -h,-15, h,QPen(QPen::darkBlue,2)));
112  Texts.append(new Text(-10, -6,"sub"));
113 
114  int i=0, y = 15-h;
115  while(i<No) {
116  i++;
117  Lines.append(new Line(-30, y,-15, y,QPen(QPen::darkBlue,2)));
118  Ports.append(new Port(-30, y));
119  Texts.append(new Text(-25,y-14,QString::number(i)));
120 
121  if(i == No) break;
122  i++;
123  Lines.append(new Line( 15, y, 30, y,QPen(QPen::darkBlue,2)));
124  Ports.append(new Port( 30, y));
125  Texts.append(new Text( 19,y-14,QString::number(i)));
126  y += 60;
127  }
128 
129  x1 = -30; y1 = -h-2;
130  x2 = 30; y2 = h+2;
131  tx = x1+4;
132  ty = y2+4;
133 }
134 
135 // ---------------------------------------------------------------------
136 // Loads the symbol for the subcircuit from the schematic file and
137 // returns the number of painting elements.
138 int Subcircuit::loadSymbol(const QString& DocName)
139 {
140  QFile file(DocName);
141  if(!file.open(IO_ReadOnly))
142  return -1;
143 
144  QString Line;
145  // *****************************************************************
146  // To strongly speed up the file read operation the whole file is
147  // read into the memory in one piece.
148  QTextStream ReadWhole(&file);
149  QString FileString = ReadWhole.read();
150  file.close();
151  QTextStream stream(&FileString, IO_ReadOnly);
152 
153 
154  // read header **************************
155  do {
156  if(stream.atEnd()) return -2;
157  Line = stream.readLine();
158  Line = Line.stripWhiteSpace();
159  } while(Line.isEmpty());
160 
161  if(Line.left(16) != "<Qucs Schematic ") // wrong file type ?
162  return -3;
163 
164  Line = Line.mid(16, Line.length()-17);
165  if(!checkVersion(Line)) // wrong version number ?
166  return -4;
167 
168  // read content *************************
169  while(!stream.atEnd()) {
170  Line = stream.readLine();
171  if(Line == "<Symbol>") break;
172  }
173 
174  x1 = y1 = INT_MAX;
175  x2 = y2 = INT_MIN;
176 
177  int z=0, Result;
178  while(!stream.atEnd()) {
179  Line = stream.readLine();
180  if(Line == "</Symbol>") {
181  x1 -= 4; // enlarge component boundings a little
182  x2 += 4;
183  y1 -= 4;
184  y2 += 4;
185  return z; // return number of ports
186  }
187 
188  Line = Line.stripWhiteSpace();
189  if(Line.at(0) != '<') return -5;
190  if(Line.at(Line.length()-1) != '>') return -6;
191  Line = Line.mid(1, Line.length()-2); // cut off start and end character
192  Result = analyseLine(Line, 1);
193  if(Result < 0) return -7; // line format error
194  z += Result;
195  }
196 
197  return -8; // field not closed
198 }
199 
200 // -------------------------------------------------------
202 {
203  QString s = Model+":"+Name;
204 
205  // output all node names
206  for(Port *p1 = Ports.first(); p1 != 0; p1 = Ports.next())
207  s += " "+p1->Connection->Name; // node names
208 
209  // type for subcircuit
210  QString f = properFileName(Props.first()->Value);
211  s += " Type=\""+properName(f)+"\"";
212 
213  // output all user defined properties
214  for(Property *pp = Props.next(); pp != 0; pp = Props.next())
215  s += " "+pp->Name+"=\""+pp->Value+"\"";
216  return s + '\n';
217 }
218 
219 // -------------------------------------------------------
221 {
222  QString f = properFileName(Props.first()->Value);
223  QString s = " " + Name + ": entity Sub_" + properName(f);
224 
225  // output all user defined properties
226  Property *pr = Props.next();
227  if (pr) {
228  s += " generic map (";
229  s += pr->Value;
230  for(pr = Props.next(); pr != 0; pr = Props.next())
231  s += ", " + pr->Value;
232  s += ")";
233  }
234 
235  // output all node names
236  s += " port map (";
237  Port *pp = Ports.first();
238  if(pp) s += pp->Connection->Name;
239  for(pp = Ports.next(); pp != 0; pp = Ports.next())
240  s += ", "+pp->Connection->Name; // node names
241 
242  s += ");\n";
243  return s;
244 }
245 
246 // -------------------------------------------------------
248 {
249  QString f = properFileName(Props.first()->Value);
250  QString s = " Sub_" + properName(f);
251 
252  // output all user defined properties
253  Property *pr = Props.next();
254  if (pr) {
255  s += " #(";
256  s += Verilog_Param(pr->Value);
257  for(pr = Props.next(); pr != 0; pr = Props.next())
258  s += ", " + Verilog_Param(pr->Value);
259  s += ")";
260  }
261 
262  // output all node names
263  s += " " + Name + " (";
264  Port *pp = Ports.first();
265  if(pp) s += pp->Connection->Name;
266  for(pp = Ports.next(); pp != 0; pp = Ports.next())
267  s += ", "+pp->Connection->Name; // node names
268 
269  s += ");\n";
270  return s;
271 }
272 
273 // -------------------------------------------------------
275 {
276  // construct full filename
277  QString FileName = Props.getFirst()->Value;
278  return properAbsFileName(FileName);
279 }