Qucs-GUI
0.0.19
|
00001 /*************************************************************************** 00002 graphictext.cpp 00003 ----------------- 00004 begin : Mon Nov 24 2003 00005 copyright : (C) 2003 by Michael Margraf 00006 email : michael.margraf@alumni.tu-berlin.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 #include "main.h" 00018 #include "mnemo.h" 00019 #include "viewpainter.h" 00020 #include "graphictext.h" 00021 #include "graphictextdialog.h" 00022 #include "schematic.h" 00023 #include "misc.h" 00024 00025 #include <QPainter> 00026 #include <QPushButton> 00027 #include <QLineEdit> 00028 #include <QTextEdit> 00029 00030 #include <cmath> 00031 00032 GraphicText::GraphicText() 00033 { 00034 Name = "Text "; 00035 isSelected = false; 00036 Color = QColor(0,0,0); 00037 Font = QucsSettings.font; 00038 cx = cy = 0; 00039 x1 = x2 = 0; 00040 y1 = y2 = 0; 00041 Angle = 0; 00042 } 00043 00044 GraphicText::~GraphicText() 00045 { 00046 } 00047 00048 // ----------------------------------------------------------------------- 00049 void GraphicText::paint(ViewPainter *p) 00050 { 00051 // keep track of painter state 00052 p->Painter->save(); 00053 00054 QMatrix wm = p->Painter->worldMatrix(); 00055 QMatrix Mat(1.0, 0.0, 0.0, 1.0, p->DX + float(cx) * p->Scale, 00056 p->DY + float(cy) * p->Scale); 00057 p->Painter->setWorldMatrix(Mat); 00058 p->Painter->rotate(-Angle); // automatically enables transformation 00059 00060 int Size = Font.pointSize(); 00061 Font.setPointSizeF( p->FontScale * float(Size) ); 00062 00063 QFont f = p->Painter->font(); 00064 p->Painter->setPen(Color); 00065 p->Painter->setFont(Font); 00066 00067 // Because of a bug in Qt 3.1, drawing this text is dangerous, if it 00068 // contains linefeeds. Qt has problems with linefeeds. It remembers the 00069 // last font metrics (within the font ???) and does not calculate it again. 00070 // The error often appears at a very different drawText function !!! 00071 int w, h; 00072 w = p->drawTextMapped(Text, 0, 0, &h); 00073 00074 if(isSelected) { 00075 p->Painter->setPen(QPen(Qt::darkGray,3)); 00076 p->Painter->drawRect(-3, -2, w+6, h+5); 00077 } 00078 00079 Font.setPointSize(Size); // restore real font size 00080 p->Painter->setWorldMatrix(wm); 00081 p->Painter->setWorldMatrixEnabled(false); 00082 00083 // restore painter state 00084 p->Painter->restore(); 00085 00086 x2 = int(float(w) / p->Scale); 00087 y2 = int(float(h) / p->Scale); 00088 p->Painter->setFont(f); 00089 } 00090 00091 // ----------------------------------------------------------------------- 00092 void GraphicText::paintScheme(Schematic *p) 00093 { 00094 // FIXME #warning QMatrix wm = p->worldMatrix(); 00095 // FIXME #warning QMatrix Mat (wm.m11(), 0.0, 0.0, wm.m22(), 00096 // FIXME #warning wm.dx() + double(cx) * wm.m11(), 00097 // FIXME #warning wm.dy() + double(cy) * wm.m22()); 00098 // FIXME #warning p->setWorldMatrix(Mat); 00099 // FIXME #warning p->rotate(-Angle); 00100 p->PostPaintEvent(_Rect, 0, 0, x2, y2); 00101 00102 // FIXME #warning p->setWorldMatrix(wm); 00103 } 00104 00105 // ------------------------------------------------------------------------ 00106 void GraphicText::getCenter(int& x, int &y) 00107 { 00108 x = cx+(x2>>1); 00109 y = cy+(y2>>1); 00110 } 00111 00112 // ----------------------------------------------------------------------- 00113 // Sets the center of the painting to x/y. 00114 void GraphicText::setCenter(int x, int y, bool relative) 00115 { 00116 if(relative) { cx += x; cy += y; } 00117 else { cx = x-(x2>>1); cy = y-(y2>>1); } 00118 } 00119 00120 // ----------------------------------------------------------------------- 00121 Painting* GraphicText::newOne() 00122 { 00123 return new GraphicText(); 00124 } 00125 00126 // -------------------------------------------------------------------------- 00127 Element* GraphicText::info(QString& Name, char* &BitmapFile, bool getNewOne) 00128 { 00129 Name = QObject::tr("Text"); 00130 BitmapFile = (char *) "text"; 00131 00132 if(getNewOne) return new GraphicText(); 00133 return 0; 00134 } 00135 00136 // ----------------------------------------------------------------------- 00137 bool GraphicText::load(const QString& s) 00138 { 00139 bool ok; 00140 00141 QString n; 00142 n = s.section(' ',1,1); // cx 00143 cx = n.toInt(&ok); 00144 if(!ok) return false; 00145 00146 n = s.section(' ',2,2); // cy 00147 cy = n.toInt(&ok); 00148 if(!ok) return false; 00149 00150 n = s.section(' ',3,3); // Size 00151 Font.setPointSize(n.toInt(&ok)); 00152 if(!ok) return false; 00153 00154 n = s.section(' ',4,4); // Color 00155 Color.setNamedColor(n); 00156 if(!Color.isValid()) return false; 00157 00158 n = s.section(' ',5,5); // Angle 00159 Angle = n.toInt(&ok); 00160 if(!ok) return false; 00161 00162 Text = s.mid(s.indexOf('"')+1); // Text (can contain " !!!) 00163 Text.truncate(Text.length()-1); 00164 if(Text.isEmpty()) return false; 00165 00166 misc::convert2Unicode(Text); 00167 // get size of text using the screen-compatible metric 00168 QFontMetrics metrics(QucsSettings.font, 0); 00169 QSize r = metrics.size(0, Text); // get overall size of text 00170 x2 = r.width(); 00171 y2 = r.height(); 00172 00173 return true; 00174 } 00175 00176 // ----------------------------------------------------------------------- 00177 QString GraphicText::save() 00178 { 00179 QString t = Text; 00180 misc::convert2ASCII(t); 00181 00182 // The 'Text' property has to be the last within the line ! 00183 QString s = Name+QString::number(cx)+" "+QString::number(cy)+" " 00184 + QString::number(Font.pointSize())+" "+Color.name()+" " 00185 + QString::number(Angle) + " \""+t+"\""; 00186 return s; 00187 } 00188 00189 // -------------------------------------------------------------------------- 00190 QString GraphicText::saveCpp() 00191 { 00192 QString t = Text; 00193 misc::convert2ASCII(t); 00194 00195 QString s = 00196 QString ("new Text (%1, %2, \"%3\", QColor (\"%4\"), %5, %6, %7)"). 00197 arg(cx).arg(cy).arg(t). 00198 arg(Color.name()).arg(Font.pointSize()). 00199 arg(cos(pi * Angle / 180.0)).arg(sin(pi * Angle / 180.0)); 00200 s = "Texts.append (" + s + ");"; 00201 return s; 00202 } 00203 00204 QString GraphicText::saveJSON() 00205 { 00206 QString t = Text; 00207 misc::convert2ASCII(t); 00208 00209 QString s = 00210 QString ("{\"type\" : \"graphictext\", " 00211 "\"x\" : %1, \"y\" : %2, \"s\" : \"%3\", " 00212 "\"color\" : \"%4\", \"size\" : %5, \"cos\" : %6, \"sin\" : %7},"). 00213 arg(cx).arg(cy).arg(t). 00214 arg(Color.name()).arg(Font.pointSize()). 00215 arg(cos(pi * Angle / 180.0)).arg(sin(pi * Angle / 180.0)); 00216 return s; 00217 } 00218 00219 // ----------------------------------------------------------------------- 00220 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid. 00221 // x/y are coordinates without scaling. 00222 void GraphicText::MouseMoving( 00223 Schematic*, int, int, int gx, int gy, 00224 Schematic *p, int x, int y, bool drawn) 00225 { 00226 // FIXME #warning p->setPen(Qt::SolidLine); 00227 if(drawn) { 00228 p->PostPaintEvent(_Line, x1+15, y1+15, x1+20, y1,0,0,true); // erase old cursor symbol 00229 p->PostPaintEvent(_Line, x1+26, y1+15, x1+21, y1,0,0,true); 00230 p->PostPaintEvent(_Line, x1+17, y1+8, x1+23, y1+8,0,0,true); 00231 } 00232 x1 = x; 00233 y1 = y; 00234 p->PostPaintEvent(_Line, x1+15, y1+15, x1+20, y1,0,0,true); // paint new cursor symbol 00235 p->PostPaintEvent(_Line, x1+26, y1+15, x1+21, y1,0,0,true); 00236 p->PostPaintEvent(_Line, x1+17, y1+8, x1+23, y1+8,0,0,true); 00237 00238 cx = gx; 00239 cy = gy; 00240 } 00241 00242 // ------------------------------------------------------------------------ 00243 bool GraphicText::MousePressing() 00244 { 00245 return Dialog(); 00246 } 00247 00248 // ------------------------------------------------------------------------ 00249 // Checks if the coordinates x/y point to the painting. 00250 // 5 is the precision the user must point onto the painting. 00251 bool GraphicText::getSelected(float fX, float fY, float) 00252 { 00253 double phi = pi/180.0*double(Angle); 00254 float sine = sin(phi), cosine = cos(phi); 00255 00256 fX -= float(cx); 00257 fY -= float(cy); 00258 int _x = int( fX*cosine - fY*sine ); 00259 int _y = int( fY*cosine + fX*sine ); 00260 00261 if(_x >= 0) if(_y >= 0) if(_x <= x2) if(_y <= y2) 00262 return true; 00263 00264 return false; 00265 } 00266 00267 // ------------------------------------------------------------------------ 00268 void GraphicText::Bounding(int& xmin, int& ymin, int& xmax, int& ymax) 00269 { 00270 double phi = pi/180.0*double(Angle); 00271 double sine = sin(phi), cosine = cos(phi); 00272 int dx = int( double(y2) * sine ); 00273 int dy = int( double(y2) * cosine ); 00274 xmin = dx; xmax = cx; 00275 ymin = dy; ymax = cy; 00276 if(xmin < 0) xmin += cx; 00277 else { xmax += xmin; xmin = cx; } 00278 if(ymin < 0) ymin += cy; 00279 else { ymax += ymin; ymin = cy; } 00280 00281 int x = cx + int( double(x2) * cosine ); 00282 if(xmax < x) xmax = x; 00283 else if(xmin > x) xmin = x; 00284 x += dx; 00285 if(xmax < x) xmax = x; 00286 else if(xmin > x) xmin = x; 00287 00288 int y = cy - int( double(x2) * sine ); 00289 if(ymax < y) ymax = y; 00290 else if(ymin > y) ymin = y; 00291 y += dy; 00292 if(ymax < y) ymax = y; 00293 else if(ymin > y) ymin = y; 00294 } 00295 00296 // ----------------------------------------------------------------------- 00297 // Rotates around the center. 00298 void GraphicText::rotate() 00299 { 00300 Angle += 90; 00301 Angle %= 360; 00302 cx -= x2 >> 1; 00303 cy -= y2 >> 1; 00304 } 00305 00306 // ----------------------------------------------------------------------- 00307 // Mirrors about center line. 00308 void GraphicText::mirrorX() 00309 { // do not mirror, because unreadable 00310 } 00311 00312 // ----------------------------------------------------------------------- 00313 // Mirrors about center line. 00314 void GraphicText::mirrorY() 00315 { // do not mirror, because unreadable 00316 } 00317 00318 // ----------------------------------------------------------------------- 00319 // Calls the property dialog for the painting and changes them accordingly. 00320 // If there were changes, it returns 'true'. 00321 bool GraphicText::Dialog() 00322 { 00323 QFont f(QucsSettings.font); // to avoid wrong text width 00324 bool changed = false; 00325 00326 GraphicTextDialog *d = new GraphicTextDialog(); 00327 00328 QPalette palette; 00329 palette.setColor(d->ColorButt->backgroundRole(), Color); 00330 d->ColorButt->setPalette(palette); 00331 00332 d->TextSize->setText(QString::number(Font.pointSize())); 00333 d->Angle->setText(QString::number(Angle)); 00334 QString _Text = Text; 00335 decode_String(_Text); // replace special characters with LaTeX commands 00336 d->text->setText(_Text); 00337 00338 if(d->exec() == QDialog::Rejected) { 00339 delete d; 00340 return false; 00341 } 00342 00343 if(Color != d->ColorButt->palette().color(d->ColorButt->backgroundRole())) { 00344 Color = d->ColorButt->palette().color(d->ColorButt->backgroundRole()); 00345 changed = true; 00346 } 00347 f.setPointSize(d->TextSize->text().toInt()); // to avoid wrong text width 00348 if(Font.pointSize() != d->TextSize->text().toInt()) { 00349 Font.setPointSize(d->TextSize->text().toInt()); 00350 changed = true; 00351 } 00352 int tmp = d->Angle->text().toInt(); 00353 if(Angle != tmp) { 00354 Angle = tmp % 360; 00355 changed = true; 00356 } 00357 00358 encode_String(d->text->toPlainText(), _Text); // create special characters 00359 if(!_Text.isEmpty()) 00360 if(_Text != Text) { 00361 Text = _Text; 00362 changed = true; 00363 } 00364 00365 // get font metric using the screen-compatible metric 00366 QFontMetrics m(f, 0); 00367 QSize s = m.size(0, Text); // get size of text 00368 x2 = s.width(); 00369 y2 = s.height(); 00370 00371 delete d; 00372 return changed; 00373 }