headingobj.cpp
author insilmaril
Tue, 21 Aug 2007 10:00:21 +0000
changeset 585 a8e9eae855f4
parent 568 b44cc0d3ed4a
child 657 8e596f73f258
permissions -rw-r--r--
Fixed wrong positioning after saving a zoomed view
     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 "<<heading.ascii()<<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