My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
textdoc.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  textdoc.cpp
3  -------------
4  begin : Sat Mar 11 2006
5  copyright : (C) 2006 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <qlabel.h>
23 #include <qaction.h>
24 #include <qpixmap.h>
25 #include <qprinter.h>
26 #include <qfileinfo.h>
27 #include <qtabwidget.h>
28 #include <qmessagebox.h>
29 #include <qpaintdevicemetrics.h>
30 #include <qfont.h>
31 #include <qpopupmenu.h>
32 #include <qsyntaxhighlighter.h>
33 
34 #include "main.h"
35 #include "qucs.h"
36 #include "textdoc.h"
37 #include "syntax.h"
38 #include "components/vhdlfile.h"
39 #include "components/verilogfile.h"
40 #include "components/vafile.h"
41 
42 TextDoc::TextDoc(QucsApp *App_, const QString& Name_) : QucsDoc(App_, Name_)
43 {
44  TextFont = QFont("Courier New");
45  TextFont.setPointSize(QucsSettings.font.pointSize()-1);
46  TextFont.setStyleHint(QFont::Courier);
47  TextFont.setFixedPitch(true);
48  setFont(TextFont);
49  setCurrentFont(TextFont);
50 
51  simulation = true;
52  Library = "";
53  Libraries = "";
54  SetChanged = false;
55  devtype = DEV_DEF;
56 
57  tmpPosX = tmpPosY = 1; // set to 1 to trigger line highlighting
58  Scale = (float)TextFont.pointSize();
59  setUndoDepth(QucsSettings.maxUndo);
60  setLanguage (Name_);
61  QFileInfo Info (Name_);
62 
63  if(App) {
64  if(Name_.isEmpty())
65  App->DocumentTab->addTab(this, QPixmap(empty_xpm),
66  QObject::tr("untitled"));
67  else
68  App->DocumentTab->addTab(this, QPixmap(empty_xpm),
69  Info.fileName());
70  // calls indirectly "becomeCurrent"
71  App->DocumentTab->setCurrentPage(App->DocumentTab->indexOf(this));
72  viewport()->setFocus();
73 
74  setWordWrap(QTextEdit::NoWrap);
75  setPaletteBackgroundColor(QucsSettings.BGColor);
76  connect(this, SIGNAL(textChanged()), SLOT(slotSetChanged()));
77  connect(this, SIGNAL(cursorPositionChanged(int, int)),
78  SLOT(slotCursorPosChanged(int, int)));
79 
80  syntaxHighlight = new SyntaxHighlighter(this);
81  syntaxHighlight->setLanguage (language);
82  }
83 }
84 
86 {
87  if(App) {
88  delete syntaxHighlight;
89  App->DocumentTab->removePage(this); // delete tab in TabBar
90  }
91 }
92 
93 // ---------------------------------------------------
94 void TextDoc::setLanguage (const QString& FileName)
95 {
96  QFileInfo Info (FileName);
97  QString ext = Info.extension (false);
98  if (ext == "vhd" || ext == "vhdl")
100  else if (ext == "v")
102  else if (ext == "va")
104  else if (ext == "m" || ext == "oct")
106  else
108 }
109 
110 // ---------------------------------------------------
111 void TextDoc::setLanguage (int lang)
112 {
113  language = lang;
114 }
115 
116 // ---------------------------------------------------
118 {
119  QFile file (DocName + ".cfg");
120  if (!file.open (IO_WriteOnly))
121  return false;
122 
123  QTextStream stream (&file);
124  stream << "Textfile settings file, Qucs " PACKAGE_VERSION "\n"
125  << "Simulation=" << simulation << "\n"
126  << "Duration=" << SimTime << "\n"
127  << "Module=" << (!simulation) << "\n"
128  << "Library=" << Library << "\n"
129  << "Libraries=" << Libraries << "\n"
130  << "ShortDesc=" << ShortDesc << "\n"
131  << "LongDesc=" << LongDesc << "\n"
132  << "Icon=" << Icon << "\n"
133  << "Recreate=" << recreate << "\n"
134  << "DeviceType=" << devtype << "\n";
135 
136  file.close ();
137  SetChanged = false;
138  return true;
139 }
140 
141 // ---------------------------------------------------
143 {
144  QFile file (DocName + ".cfg");
145  if (!file.open (IO_ReadOnly))
146  return false;
147 
148  QTextStream stream (&file);
149  QString Line, Setting;
150 
151  bool ok;
152  while (!stream.atEnd ()) {
153  Line = stream.readLine ();
154  Setting = Line.section ('=', 0, 0);
155  Line = Line.section ('=', 1).stripWhiteSpace ();
156  if (Setting == "Simulation") {
157  simulation = Line.toInt (&ok);
158  } else if (Setting == "Duration") {
159  SimTime = Line;
160  } else if (Setting == "Module") {
161  } else if (Setting == "Library") {
162  Library = Line;
163  } else if (Setting == "Libraries") {
164  Libraries = Line;
165  } else if (Setting == "ShortDesc") {
166  ShortDesc = Line;
167  } else if (Setting == "LongDesc") {
168  LongDesc = Line;
169  } else if (Setting == "Icon") {
170  Icon = Line;
171  } else if (Setting == "Recreate") {
172  recreate = Line.toInt (&ok);
173  } else if (Setting == "DeviceType") {
174  devtype = Line.toInt (&ok);
175  }
176  }
177 
178  file.close ();
179  return true;
180 }
181 
182 // ---------------------------------------------------
183 void TextDoc::setName (const QString& Name_)
184 {
185  DocName = Name_;
187 
188  QFileInfo Info (DocName);
189  if (App)
190  App->DocumentTab->setTabLabel (this, Info.fileName ());
191 
192  DataSet = Info.baseName (true) + ".dat";
193  DataDisplay = Info.baseName (true) + ".dpl";
194  if(Info.extension(false) == "m" || Info.extension(false) == "oct")
195  SimTime = "1";
196 }
197 
198 // ---------------------------------------------------
200 {
201  int x, y;
202  getCursorPosition (&x, &y);
203  slotCursorPosChanged (x, y);
204  viewport()->setFocus ();
205 
206  if (isUndoAvailable ())
207  App->undo->setEnabled (true);
208  else
209  App->undo->setEnabled (false);
210  if (isRedoAvailable ())
211  App->redo->setEnabled (true);
212  else
213  App->redo->setEnabled (false);
214 
215  // update appropriate menu entries
216  App->symEdit->setMenuText (tr("Edit Text Symbol"));
217  App->symEdit->setStatusTip (tr("Edits the symbol for this text document"));
218  App->symEdit->setWhatsThis (
219  tr("Edit Text Symbol\n\nEdits the symbol for this text document"));
220 
221  if (language == LANG_VHDL) {
222  App->insEntity->setMenuText (tr("VHDL entity"));
223  App->insEntity->setStatusTip (tr("Inserts skeleton of VHDL entity"));
224  App->insEntity->setWhatsThis (
225  tr("VHDL entity\n\nInserts the skeleton of a VHDL entity"));
226  }
227  else if (language == LANG_VERILOG || language == LANG_VERILOGA) {
228  App->insEntity->setMenuText (tr("Verilog module"));
229  App->insEntity->setStatusTip (tr("Inserts skeleton of Verilog module"));
230  App->insEntity->setWhatsThis (
231  tr("Verilog module\n\nInserts the skeleton of a Verilog module"));
232  }
233  else if (language == LANG_OCTAVE) {
234  App->insEntity->setMenuText (tr("Octave function"));
235  App->insEntity->setStatusTip (tr("Inserts skeleton of Octave function"));
236  App->insEntity->setWhatsThis (
237  tr("Octave function\n\nInserts the skeleton of a Octave function"));
238  }
239  App->simulate->setEnabled (true);
240  App->editActivate->setEnabled (true);
241 }
242 
243 // ---------------------------------------------------
245 {
246  if(tmpPosX > x)
247  clearParagraphBackground(tmpPosX);
248  else
249  for(int z=tmpPosX; z<x; z++)
250  clearParagraphBackground(z);
251  if(tmpPosX != x)
252  setParagraphBackgroundColor(x, QColor(240, 240, 255));
253  App->printCursorPosition(x+1, y+1);
254  tmpPosX = x;
255  tmpPosY = y;
256 }
257 
258 // ---------------------------------------------------
260 {
261  if((isModified() && !DocChanged) || SetChanged) {
262  App->DocumentTab->setTabIconSet(this, QPixmap(smallsave_xpm));
263  DocChanged = true;
264  }
265  else if((!isModified() && DocChanged)) {
266  App->DocumentTab->setTabIconSet(this, QPixmap(empty_xpm));
267  DocChanged = false;
268  }
269 
270  App->undo->setEnabled(isUndoAvailable());
271  App->redo->setEnabled(isRedoAvailable());
272 }
273 
274 // ---------------------------------------------------
275 QPopupMenu *TextDoc::createPopupMenu( const QPoint &pos )
276 {
277  QPopupMenu *popup = QTextEdit::createPopupMenu( pos );
278  if (language != LANG_OCTAVE) {
279  App->fileSettings->addTo(popup);
280  }
281  return popup;
282 }
283 
284 // ---------------------------------------------------
286 {
287  QFile file (DocName);
288  if (!file.open (IO_ReadOnly))
289  return false;
291 
292  QTextStream stream (&file);
293  setText (stream.read ());
294  setModified (false);
295  slotSetChanged ();
296  file.close ();
297  lastSaved = QDateTime::currentDateTime ();
298 
299  loadSettings ();
300  SimOpenDpl = simulation ? true : false;
301  return true;
302 }
303 
304 // ---------------------------------------------------
306 {
307  saveSettings ();
308 
309  QFile file (DocName);
310  if (!file.open (IO_WriteOnly))
311  return -1;
313 
314  QTextStream stream (&file);
315  stream << text ();
316  setModified (false);
317  slotSetChanged ();
318  file.close ();
319 
320  QFileInfo Info (DocName);
321  lastSaved = Info.lastModified ();
322  return 0;
323 }
324 
325 // -----------------------------------------------------------
326 void TextDoc::print(QPrinter *Printer, QPainter *Painter, bool printAll, bool)
327 {
328  Painter->setFont(TextFont);
329 
330  sync(); // formatting whole text
331 
332  QPaintDeviceMetrics smetrics(QPainter(this).device());
333  QPaintDeviceMetrics pmetrics(Painter->device());
334  int margin = 54; // margin at each side (unit is point)
335  int marginX = margin * pmetrics.logicalDpiX() / smetrics.logicalDpiX();
336  int marginY = margin * pmetrics.logicalDpiY() / smetrics.logicalDpiY();
337  QRect printArea(
338  marginX, marginY, pmetrics.width() - 2*marginX,
339  pmetrics.height() - 2*marginY - Painter->fontMetrics().lineSpacing());
340 
341  int linesPerPage = printArea.height() / Painter->fontMetrics().lineSpacing();
342 
343  int PageCount, PageNo = 1;
344  QString s, printText;
345  if(printAll) {
346  printText = text();
347  PageCount = paragraphs();
348  }
349  else {
350  int line1, col1, line2, col2;
351  printText = selectedText();
352  getSelection(&line1, &col1, &line2, &col2);
353  if(line1 < 0) {
354  QMessageBox::critical(this, tr("Error"), tr("There is no selection!"));
355  return;
356  }
357  PageCount = line2 - line1 + 1;
358  }
359  PageCount = (PageCount + linesPerPage - 1) / linesPerPage;
360 
361  for(;;) {
362  if(Printer->aborted())
363  break;
364  Painter->drawText(printArea, 0, printText.section('\n', 0, linesPerPage-1));
365  printText = printText.section('\n', linesPerPage);
366 
367  s = tr("Page %1 of %2").arg(PageNo).arg(PageCount);
368  Painter->drawText(printArea.right() - Painter->fontMetrics().width(s),
369  printArea.bottom() + Painter->fontMetrics().lineSpacing(), s);
370  if(printText.isEmpty())
371  break;
372  Printer->newPage();
373  PageNo++;
374  }
375 }
376 
377 // ---------------------------------------------------
378 float TextDoc::zoomBy(float s)
379 {
380  if(s < 1.0f) s = -1.0f/s;
381  Scale += s;
382  if(Scale > 40.0f) Scale = 40.0f;
383  if(Scale < 4.0f) Scale = 4.0f;
384  zoomTo((int)(Scale+0.5f));
385  return Scale;
386 }
387 
388 // ---------------------------------------------------
390 {
391  sync();
392  Scale *= float(visibleHeight()) / float(contentsHeight());
393  if(Scale > 40.0f) Scale = 40.0f;
394  if(Scale < 4.0f) Scale = 4.0f;
395  zoomTo((int)(Scale+0.5f));
396 }
397 
398 // ---------------------------------------------------
400 {
401  Scale = (float)TextFont.pointSize();
402  zoomTo(TextFont.pointSize());
403 }
404 
405 // ---------------------------------------------------
406 bool TextDoc::loadSimulationTime(QString& Time)
407 {
408  if(!SimTime.isEmpty()) {
409  Time = SimTime;
410  return true;
411  }
412 
413  return false;
414 }
415 
416 // ---------------------------------------------------
418 {
419  QString s = selectedText ();
420  if (s.isEmpty ())
421  return;
422 
423  // use comment string indicator depending on language
424  QString co;
425  int cl;
426  switch (language) {
427  case LANG_VHDL:
428  co = "--"; cl = 2;
429  break;
430  case LANG_VERILOG:
431  case LANG_VERILOGA:
432  co = "//"; cl = 2;
433  break;
434  case LANG_OCTAVE:
435  co = "%"; cl = 1;
436  break;
437  default:
438  co = ""; cl = 0;
439  break;
440  }
441 
442  if (s.left (cl) == co)
443  s.remove (0, cl);
444  else
445  s = co + s;
446 
447  for (int i = s.length () - cl; i >= 0; i--)
448  if (s.at (i) == '\n') {
449  if (s.mid (i+1, cl) == co)
450  s.remove(i+1, cl);
451  else
452  s.insert (i+1, co);
453  }
454  insert (s);
455 }
456 
457 // ---------------------------------------------------
459 {
460  if (language == LANG_VHDL)
461  insert ("entity is\n port ( : in bit);\nend;\n"
462  "architecture of is\n signal : bit;\nbegin\n\nend;\n\n");
463  else if (language == LANG_VERILOG)
464  insert ("module ( );\ninput ;\noutput ;\nbegin\n\nend\n"
465  "endmodule\n\n");
466  else if (language == LANG_OCTAVE)
467  insert ("function = ( )\n"
468  "endfunction\n\n");
469 }
470 
471 // ---------------------------------------------------
473 {
474  switch (language) {
475  case LANG_VHDL:
476  {
477  VHDL_File_Info VInfo (text ());
478  return VInfo.EntityName;
479  }
480  case LANG_VERILOG:
481  {
482  Verilog_File_Info VInfo (text ());
483  return VInfo.ModuleName;
484  }
485  case LANG_VERILOGA:
486  {
487  VerilogA_File_Info VInfo (text ());
488  return VInfo.ModuleName;
489  }
490  case LANG_OCTAVE:
491  {
492  QFileInfo Info (DocName);
493  return Info.baseName (true);
494  }
495  default:
496  return "";
497  }
498 }