initial import
[vym] / headingobj.cpp
1 #include "headingobj.h"
2 #include <qregexp.h>
3
4 /////////////////////////////////////////////////////////////////
5 // HeadingObj
6 /////////////////////////////////////////////////////////////////
7 HeadingObj::HeadingObj() : MapObj()
8 {
9 //    cout << "Const HeadingObj ()\n";
10     init ();
11 }
12
13 HeadingObj::HeadingObj(QGraphicsScene *s) :MapObj(s)
14 {
15 //    cout << "Const HeadingObj (s)\n";
16     init ();
17 }
18
19 HeadingObj::~HeadingObj()
20 {
21 //      cout << "Destr. HeadingObj "<<qPrintable(heading)<<endl;
22         while (!textline.isEmpty())
23                 delete textline.takeFirst();
24 }
25
26 void HeadingObj::init()
27 {
28     textwidth=40;
29     color=QColor ("black");
30     font=QFont();
31         heading="";
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 //QGraphicsSimpleTextItem* HeadingObj::newLine(QString s)
94 QGraphicsTextItem* HeadingObj::newLine(QString s)
95 {
96     //QGraphicsSimpleTextItem *t=new QGraphicsSimpleTextItem (s,0,scene);
97     QGraphicsTextItem *t=new QGraphicsTextItem (s,0,scene);
98     t->setFont (font);
99     t->setZValue(Z_TEXT);
100         // TextItem
101     t->setDefaultTextColor(color);
102         // SimpleTextItem
103     //t->setBrush(color);
104     return t;
105 }
106
107 void HeadingObj::setText (QString s)
108 {
109     heading=s;
110
111     // remove old textlines and prepare generating new ones
112         while (!textline.isEmpty())
113                 delete textline.takeFirst();
114
115         if (s.startsWith("<html>"))
116         {
117                 QGraphicsTextItem *t=new QGraphicsTextItem ();
118                 t->setFont (font);
119                 t->setZValue(Z_TEXT);
120                 t->setHtml (s);
121                 t->setDefaultTextColor(color);
122                 scene->addItem (t);
123                 textline.append (t);
124                 setVisibility (visible);
125                 move (absPos.x(),absPos.y());
126                 calcBBoxSize();
127                 return;
128         }
129
130         // prevent empty textline, so at least a small selection stays
131         // visible for this heading
132         if (s.length()==0) s="  ";
133
134     int i=0;    // index for actual search for ws
135     int j=0;    // index of last ws
136         int k=0;        // index of "<br>" or similar linebreak
137         int br=0;       // width of found break, e.g. for <br> it is 4
138         QRegExp re("<br.*/>");
139         re.setMinimal (true);
140
141     // set the text and wrap lines
142     while (s.length()>0)
143     {
144                 // ok, some people wanted manual linebreaks, here we go
145                 k=re.search (s,i);
146                 if (k>=0)
147                 {
148                         br=re.cap(0).length();
149                         i=k;
150                 } else
151                         i=s.find (" ",i,false);
152                 if (i<0 && j==0)
153                 {   // no ws found at all in s
154                         // append whole s
155                         textline.append (newLine(s));
156                         s="";
157                 } else
158                 {
159                         if (i<0 && j>0)
160                         {       // no ws found in actual search
161                                 if (s.length()<=textwidth)
162                                 {
163                                         textline.append (newLine(s));
164                                         s="";
165                                 } else
166                                 {
167                                         textline.append (newLine(s.left(j)));
168                                         s=s.mid(j+1,s.length());
169                                         j=0;
170                                 }                   
171                         } else
172                         {
173                                 if (i>= 0 && i<=static_cast <int> (textwidth))
174                                 {   // there is a ws in textwidth
175                                         if (br>0)
176                                         {
177                                                 // here is a linebreak
178                                                 textline.append (newLine(s.left(i)));
179                                                 s=s.mid(i+br,s.length());
180                                                 i=0;
181                                                 j=0;
182                                                 br=0;
183                                         } else
184                                         {
185                                                 j=i;
186                                                 i++;
187                                         }
188                                 } else
189                                 {
190                                         if (i>static_cast <int> (textwidth)  )
191                                         {       
192                                                 if (j>0)
193                                                 {   // a ws out of textwidth, but we have also one in
194                                                         textline.append (newLine(s.left(j)));
195                                                         s=s.mid(j+1,s.length());
196                                                         i=0;
197                                                         j=0;
198                                                 } else
199                                                 {   // a ws out of text, but none in
200                                                         textline.append (newLine(s.left(i)));
201                                                         s=s.mid(i+1,s.length());
202                                                         i=0;
203                                                 }
204                                         }
205                                 } 
206                         }         
207                 }                   
208     }
209         setVisibility (visible);
210         move (absPos.x(),absPos.y());
211         calcBBoxSize();
212 }
213
214 QString HeadingObj::text ()
215 {
216     return heading;
217 }
218
219 void HeadingObj::setFont (QFont f)
220 {
221     if (font!=f) 
222     {
223                 font=f;
224                 setText (text());
225     }
226 }
227
228 QFont HeadingObj::getFont()
229 {
230     return font;
231 }    
232         
233         
234 void HeadingObj::setColor (QColor c)
235 {
236     if (color!=c)
237     {
238                 color=c;
239                 for (int i=0; i<textline.size(); ++i)
240                         // TextItem
241                         textline.at(i)->setDefaultTextColor(c);
242                         // SimpleTextItem
243                         //textline.at(i)->setBrush(c);
244     }       
245 }
246
247 QColor HeadingObj::getColor()
248 {
249     return color;
250 }    
251
252 void HeadingObj::setVisibility (bool v)
253 {
254     MapObj::setVisibility(v);
255         for (int i=0; i<textline.size(); ++i)
256                 if (v)
257                         textline.at(i)->show();
258                 else
259                         textline.at(i)->hide();
260 }
261
262 qreal HeadingObj::getHeight ()
263 {
264         return bbox.height();
265 }
266
267 qreal HeadingObj::getWidth()
268 {
269         return bbox.width();
270 }
271