My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
graphictext.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  graphictext.cpp
3  -----------------
4  begin : Mon Nov 24 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 #include "main.h"
19 #include "mnemo.h"
20 #include "viewpainter.h"
21 #include "graphictext.h"
22 #include "graphictextdialog.h"
23 
24 #include <qwidget.h>
25 #include <qpainter.h>
26 #include <qlineedit.h>
27 #include <qtextedit.h>
28 #include <qpushbutton.h>
29 
30 #include <math.h>
31 
32 
34 {
35  Name = "Text ";
36  isSelected = false;
37  Color = QColor(0,0,0);
39  cx = cy = 0;
40  x1 = x2 = 0;
41  y1 = y2 = 0;
42  Angle = 0;
43 }
44 
46 {
47 }
48 
49 // -----------------------------------------------------------------------
51 {
52  QWMatrix wm = p->Painter->worldMatrix();
53  QWMatrix Mat(1.0, 0.0, 0.0, 1.0, p->DX + float(cx) * p->Scale,
54  p->DY + float(cy) * p->Scale);
55  p->Painter->setWorldMatrix(Mat);
56  p->Painter->rotate(-Angle); // automatically enables transformation
57 
58  int Size = Font.pointSize();
59  Font.setPointSizeFloat( p->FontScale * float(Size) );
60 
61  QFont f = p->Painter->font();
62  p->Painter->setPen(Color);
63  p->Painter->setFont(Font);
64 
65  // Because of a bug in Qt 3.1, drawing this text is dangerous, if it
66  // contains linefeeds. Qt has problems with linefeeds. It remembers the
67  // last font metrics (within the font ???) and does not calculate it again.
68  // The error often appears at a very different drawText function !!!
69  int w, h;
70  w = p->drawTextMapped(Text, 0, 0, &h);
71 
72  if(isSelected) {
73  p->Painter->setPen(QPen(QPen::darkGray,3));
74  p->Painter->drawRect(-3, -2, w+6, h+5);
75  }
76 
77  Font.setPointSize(Size); // restore real font size
78  p->Painter->setWorldMatrix(wm);
79  p->Painter->setWorldXForm(false);
80  x2 = int(float(w) / p->Scale);
81  y2 = int(float(h) / p->Scale);
82  p->Painter->setFont(f);
83 }
84 
85 // -----------------------------------------------------------------------
86 void GraphicText::paintScheme(QPainter *p)
87 {
88  QWMatrix wm = p->worldMatrix();
89  QWMatrix Mat (wm.m11(), 0.0, 0.0, wm.m22(),
90  wm.dx() + double(cx) * wm.m11(),
91  wm.dy() + double(cy) * wm.m22());
92  p->setWorldMatrix(Mat);
93  p->rotate(-Angle);
94  p->drawRect(0, 0, x2, y2);
95 
96  p->setWorldMatrix(wm);
97 }
98 
99 // ------------------------------------------------------------------------
100 void GraphicText::getCenter(int& x, int &y)
101 {
102  x = cx+(x2>>1);
103  y = cy+(y2>>1);
104 }
105 
106 // -----------------------------------------------------------------------
107 // Sets the center of the painting to x/y.
108 void GraphicText::setCenter(int x, int y, bool relative)
109 {
110  if(relative) { cx += x; cy += y; }
111  else { cx = x-(x2>>1); cy = y-(y2>>1); }
112 }
113 
114 // -----------------------------------------------------------------------
116 {
117  return new GraphicText();
118 }
119 
120 // --------------------------------------------------------------------------
121 Element* GraphicText::info(QString& Name, char* &BitmapFile, bool getNewOne)
122 {
123  Name = QObject::tr("Text");
124  BitmapFile = (char *) "text";
125 
126  if(getNewOne) return new GraphicText();
127  return 0;
128 }
129 
130 // -----------------------------------------------------------------------
131 bool GraphicText::load(const QString& s)
132 {
133  bool ok;
134 
135  QString n;
136  n = s.section(' ',1,1); // cx
137  cx = n.toInt(&ok);
138  if(!ok) return false;
139 
140  n = s.section(' ',2,2); // cy
141  cy = n.toInt(&ok);
142  if(!ok) return false;
143 
144  n = s.section(' ',3,3); // Size
145  Font.setPointSize(n.toInt(&ok));
146  if(!ok) return false;
147 
148  n = s.section(' ',4,4); // Color
149  Color.setNamedColor(n);
150  if(!Color.isValid()) return false;
151 
152  n = s.section(' ',5,5); // Angle
153  Angle = n.toInt(&ok);
154  if(!ok) return false;
155 
156  Text = s.mid(s.find('"')+1); // Text (can contain " !!!)
157  Text.truncate(Text.length()-1);
158  if(Text.isEmpty()) return false;
159 
161  QFontMetrics metrics(Font);
162  QSize r = metrics.size(0, Text); // get size of text
163  x2 = r.width();
164  y2 = r.height();
165 
166  return true;
167 }
168 
169 // -----------------------------------------------------------------------
171 {
172  QString t = Text;
173  convert2ASCII(t);
174 
175  // The 'Text' property has to be the last within the line !
176  QString s = Name+QString::number(cx)+" "+QString::number(cy)+" "
177  + QString::number(Font.pointSize())+" "+Color.name()+" "
178  + QString::number(Angle) + " \""+t+"\"";
179  return s;
180 }
181 
182 // --------------------------------------------------------------------------
184 {
185  QString t = Text;
186  convert2ASCII(t);
187 
188  QString s =
189  QString ("new Text (%1, %2, \"%3\", QColor (\"%4\"), %5, %6, %7)").
190  arg(cx).arg(cy).arg(t).
191  arg(Color.name()).arg(Font.pointSize()).
192  arg(cos(M_PI * Angle / 180.0)).arg(sin(M_PI * Angle / 180.0));
193  s = "Texts.append (" + s + ");";
194  return s;
195 }
196 
197 // -----------------------------------------------------------------------
198 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
199 // x/y are coordinates without scaling.
201  QPainter*, int, int, int gx, int gy,
202  QPainter *p, int x, int y, bool drawn)
203 {
204  p->setPen(Qt::SolidLine);
205  if(drawn) {
206  p->drawLine(x1+15, y1+15, x1+20, y1); // erase old cursor symbol
207  p->drawLine(x1+26, y1+15, x1+21, y1);
208  p->drawLine(x1+17, y1+8, x1+23, y1+8);
209  }
210  x1 = x;
211  y1 = y;
212  p->drawLine(x1+15, y1+15, x1+20, y1); // paint new cursor symbol
213  p->drawLine(x1+26, y1+15, x1+21, y1);
214  p->drawLine(x1+17, y1+8, x1+23, y1+8);
215 
216  cx = gx;
217  cy = gy;
218 }
219 
220 // ------------------------------------------------------------------------
222 {
223  return Dialog();
224 }
225 
226 // ------------------------------------------------------------------------
227 // Checks if the coordinates x/y point to the painting.
228 // 5 is the precision the user must point onto the painting.
229 bool GraphicText::getSelected(float fX, float fY, float)
230 {
231  double phi = M_PI/180.0*double(Angle);
232  float sine = sin(phi), cosine = cos(phi);
233 
234  fX -= float(cx);
235  fY -= float(cy);
236  int _x = int( fX*cosine - fY*sine );
237  int _y = int( fY*cosine + fX*sine );
238 
239  if(_x >= 0) if(_y >= 0) if(_x <= x2) if(_y <= y2)
240  return true;
241 
242  return false;
243 }
244 
245 // ------------------------------------------------------------------------
246 void GraphicText::Bounding(int& xmin, int& ymin, int& xmax, int& ymax)
247 {
248  double phi = M_PI/180.0*double(Angle);
249  double sine = sin(phi), cosine = cos(phi);
250  int dx = int( double(y2) * sine );
251  int dy = int( double(y2) * cosine );
252  xmin = dx; xmax = cx;
253  ymin = dy; ymax = cy;
254  if(xmin < 0) xmin += cx;
255  else { xmax += xmin; xmin = cx; }
256  if(ymin < 0) ymin += cy;
257  else { ymax += ymin; ymin = cy; }
258 
259  int x = cx + int( double(x2) * cosine );
260  if(xmax < x) xmax = x;
261  else if(xmin > x) xmin = x;
262  x += dx;
263  if(xmax < x) xmax = x;
264  else if(xmin > x) xmin = x;
265 
266  int y = cy - int( double(x2) * sine );
267  if(ymax < y) ymax = y;
268  else if(ymin > y) ymin = y;
269  y += dy;
270  if(ymax < y) ymax = y;
271  else if(ymin > y) ymin = y;
272 }
273 
274 // -----------------------------------------------------------------------
275 // Rotates around the center.
277 {
278  Angle += 90;
279  Angle %= 360;
280  cx -= x2 >> 1;
281  cy -= y2 >> 1;
282 }
283 
284 // -----------------------------------------------------------------------
285 // Mirrors about center line.
287 { // do not mirror, because unreadable
288 }
289 
290 // -----------------------------------------------------------------------
291 // Mirrors about center line.
293 { // do not mirror, because unreadable
294 }
295 
296 // -----------------------------------------------------------------------
297 // Calls the property dialog for the painting and changes them accordingly.
298 // If there were changes, it returns 'true'.
300 {
301  QFont f(QucsSettings.font); // to avoid wrong text width
302  bool changed = false;
303 
305  d->ColorButt->setPaletteBackgroundColor(Color);
306  d->TextSize->setText(QString::number(Font.pointSize()));
307  d->Angle->setText(QString::number(Angle));
308  QString _Text = Text;
309  decode_String(_Text); // replace special characters with LaTeX commands
310  d->text->setText(_Text);
311 
312  if(d->exec() == QDialog::Rejected) {
313  delete d;
314  return false;
315  }
316 
317  if(Color != d->ColorButt->paletteBackgroundColor()) {
318  Color = d->ColorButt->paletteBackgroundColor();
319  changed = true;
320  }
321  f.setPointSize(d->TextSize->text().toInt()); // to avoid wrong text width
322  if(Font.pointSize() != d->TextSize->text().toInt()) {
323  Font.setPointSize(d->TextSize->text().toInt());
324  changed = true;
325  }
326  int tmp = d->Angle->text().toInt();
327  if(Angle != tmp) {
328  Angle = tmp % 360;
329  changed = true;
330  }
331 
332  encode_String(d->text->text(), _Text); // create special characters
333  if(!_Text.isEmpty())
334  if(_Text != Text) {
335  Text = _Text;
336  changed = true;
337  }
338 
339  QFontMetrics m(f);
340  QSize s = m.size(0, Text); // get size of text
341  x2 = s.width();
342  y2 = s.height();
343 
344  delete d;
345  return changed;
346 }