]> git.sven.stormbind.net Git - sven/vym.git/blob - headingobj.cpp
Import Upstream version 2.6.11
[sven/vym.git] / headingobj.cpp
1 #include <QDebug>
2 #include <QRegExp>
3 #include <QGraphicsScene>
4
5 #include "headingobj.h"
6
7 extern bool debug;
8
9 /////////////////////////////////////////////////////////////////
10 // HeadingObj
11 /////////////////////////////////////////////////////////////////
12 HeadingObj::HeadingObj(QGraphicsItem *parent) :MapObj(parent)
13 {
14     //qDebug() << "Const HeadingObj (s) ";
15     init ();
16 }
17
18 HeadingObj::~HeadingObj()
19 {
20 //  qDebug() << "Destr. HeadingObj "<<heading;
21     while (!textline.isEmpty())
22         delete textline.takeFirst();
23 }
24
25 void HeadingObj::init()
26 {
27     textwidth=40;
28     color=QColor ("black");
29     font=QFont();
30     heading="";
31     angle=0;    
32 }
33
34 void HeadingObj::copy(HeadingObj *other)
35 {
36     MapObj::copy (other);
37     textwidth=other->textwidth;
38     color=other->color;
39     font=other->font;
40     setText (other->text() );
41 }
42
43 void HeadingObj::move(double x, double y)
44 {
45     MapObj::move(x,y);
46
47     qreal h;    // height of a textline
48     qreal ho;   // offset of height while drawing all lines
49
50     if (!textline.isEmpty() )
51         h=textline.first()->boundingRect().height();
52     else
53         h=2;
54     ho=0;
55     for (int i=0; i<textline.size(); ++i)
56     {
57         textline.at(i)->setPos(x,y+ho);
58         ho=ho+h;
59     }   
60 }
61
62
63 void HeadingObj::moveBy(double x, double y)
64 {
65     move (x+absPos.x(),y+absPos.y() );
66 }
67
68 void HeadingObj::positionBBox()
69 {
70     bbox.setX (absPos.x());
71     bbox.setY (absPos.y());
72 }
73
74 void HeadingObj::calcBBoxSize()
75 {   
76     qreal w=0;
77     qreal h=0;
78     // Using Backspace an empty heading might easily be created, then there
79     // would be textline.first()==NULL This can be worked around by the following, but
80     // then no selection would be visible, thus we prevent it in ::setText()
81     if (!textline.isEmpty() )
82     {
83         for (int i=0; i<textline.size(); i++)
84         {
85             h+=textline.at(i)->boundingRect().height();
86             if (w<textline.at(i)->boundingRect().width() )
87                 w=textline.at(i)->boundingRect().width();
88         }   
89     } 
90     bbox.setSize (QSizeF(w,h));
91 }
92
93 QGraphicsTextItem* HeadingObj::newLine(QString s)  
94 {
95     QGraphicsTextItem *t=new QGraphicsTextItem (s,parentItem());
96     t->setFont (font);
97     t->setZValue(dZ_TEXT);
98     t->setDefaultTextColor(color);
99     t->setRotation (angle);
100     return t;
101 }
102
103 void HeadingObj::setTransformOriginPoint (const QPointF & p)
104 {
105     for (int i=0; i<textline.size(); i++)
106     {
107         textline.at(i)->setTransformOriginPoint (p);
108     }
109 }
110
111 void HeadingObj::setRotation (const qreal &a)
112 {
113     angle=a;
114     for (int i=0; i<textline.size(); i++)
115         textline.at(i)->setRotation (angle);
116 }
117
118 qreal HeadingObj::getRotation()
119 {
120     return angle;
121 }
122
123 void HeadingObj::setText (QString s)  
124 {
125     heading=s;
126
127     // remove old textlines and prepare generating new ones
128     while (!textline.isEmpty())
129         delete textline.takeFirst();
130
131     if (s.startsWith("<html>")||
132         s.startsWith("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">")
133     )
134     {
135         QGraphicsTextItem *t=new QGraphicsTextItem ();
136         t->setFont (font);
137         t->setZValue(dZ_TEXT);
138         t->setHtml (s);
139         t->setDefaultTextColor(color);
140         t->setRotation (angle);
141         scene()->addItem (t);
142         textline.append (t);
143     } else
144     {
145         // prevent empty textline, so at least a small selection stays
146         // visible for this heading
147         if (s.length()==0) s="  ";
148
149         int i=0;        // index for actual search for ws
150         int j=0;        // index of last ws
151         int k=0;        // index of "<br>" or similar linebreak
152         int br=0;       // width of found break, e.g. for <br> it is 4
153         QRegExp re("<br.*/>");
154         re.setMinimal (true);
155
156         // set the text and wrap lines
157         while (s.length()>0)
158         {
159             // ok, some people wanted manual linebreaks, here we go
160             k=re.indexIn (s,i);
161             if (k>=0)
162             {
163                 br=re.cap(0).length();
164                 i=k;
165             } else
166                 i=s.indexOf (" ",i);
167             if (i<0 && j==0)
168             {   // no ws found at all in s
169                 // append whole s
170                 textline.append (newLine(s));
171                 s="";
172             } else
173             {
174                 if (i<0 && j>0)
175                 {       // no ws found in actual search
176                     if (s.length()<=textwidth)
177                     {
178                         textline.append (newLine(s));
179                         s="";
180                     } else
181                     {
182                         textline.append (newLine(s.left(j)));
183                         s=s.mid(j+1,s.length());
184                         j=0;
185                     }       
186                 } else
187                 {
188                     if (i>= 0 && i<=static_cast <int> (textwidth))
189                     {   // there is a ws in textwidth
190                         if (br>0)
191                         {
192                             // here is a linebreak
193                             textline.append (newLine(s.left(i)));
194                             s=s.mid(i+br,s.length());
195                             i=0;
196                             j=0;
197                             br=0;
198                         } else
199                         {
200                             j=i;
201                             i++;
202                         }
203                     } else
204                     {
205                         if (i>static_cast <int> (textwidth)  )
206                         {       
207                             if (j>0)
208                             {   // a ws out of textwidth, but we have also one in
209                                 textline.append (newLine(s.left(j)));
210                                 s=s.mid(j+1,s.length());
211                                 i=0;
212                                 j=0;
213                             } else
214                             {   // a ws out of text, but none in
215                                 textline.append (newLine(s.left(i)));
216                                 s=s.mid(i+1,s.length());
217                                 i=0;
218                             }
219                         }
220                     } 
221                 }         
222             }       
223         }
224     } // ASCII heading with multiple lines
225     setVisibility (visible);
226     move (absPos.x(),absPos.y());
227     calcBBoxSize();
228 }
229
230 QString HeadingObj::text ()
231 {
232     return heading;
233 }
234
235 void HeadingObj::setFont (QFont f)
236 {
237     if (font!=f) 
238     {
239         font=f;
240         setText (text());
241     }
242 }
243
244 QFont HeadingObj::getFont()
245 {
246     return font;
247 }    
248     
249     
250 void HeadingObj::setColor (QColor c)
251 {
252     if (color!=c)
253     {
254         color=c;
255         for (int i=0; i<textline.size(); ++i)
256             // TextItem
257             textline.at(i)->setDefaultTextColor(c);
258             // SimpleTextItem
259             //textline.at(i)->setBrush(c);
260     }       
261 }
262
263 QColor HeadingObj::getColor()
264 {
265     return color;
266 }    
267
268 void HeadingObj::setZValue (double z)
269 {
270     for (int i=0; i<textline.size(); ++i)
271         textline.at(i)->setZValue (z);
272 }
273
274 void HeadingObj::setVisibility (bool v)
275 {
276     MapObj::setVisibility(v);
277     for (int i=0; i<textline.size(); ++i)
278         if (v)
279             textline.at(i)->show();
280         else
281             textline.at(i)->hide();
282 }
283
284 qreal HeadingObj::getHeight ()
285 {
286     return bbox.height();
287 }
288
289 qreal HeadingObj::getWidth()
290 {
291     return bbox.width();
292 }
293