1 /***************************************************************************
2 kimearea.cpp - description
3 -------------------
4 begin : Thu Jun 14 2001
5 copyright : (C) 2001 by Jan Schaefer
6 email : janschaefer@users.sourceforge.net
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 "kimearea.h"
19
20 #include <QBitmap>
21 #include <QBrush>
22 #include <QColor>
23 #include <QImage>
24 #include <QPainter>
25 #include <QPalette>
26 #include <QPen>
27 #include <QPixmap>
28 #include <QPolygon>
29
30 #include "kimagemapeditor_debug.h"
31
32 #include "kimecommon.h"
33
34
35 // The size of Selection Points
36
SelectionPoint(QPoint p,QCursor c)37 SelectionPoint::SelectionPoint(QPoint p, QCursor c)
38 {
39 point = p;
40 state = Normal;
41 _cursor = c;
42 }
43
~SelectionPoint()44 SelectionPoint::~SelectionPoint() {
45 }
46
setState(SelectionPoint::State s)47 void SelectionPoint::setState(SelectionPoint::State s) {
48 state = s;
49 }
50
getState() const51 SelectionPoint::State SelectionPoint::getState() const {
52 return state;
53 }
54
setPoint(QPoint p)55 void SelectionPoint::setPoint(QPoint p) {
56 point = p;
57 }
58
translate(int dx,int dy)59 void SelectionPoint::translate(int dx, int dy) {
60 point += QPoint(dx,dy);
61 }
62
63
getPoint() const64 QPoint SelectionPoint::getPoint() const {
65 return point;
66 }
67
getRect() const68 QRect SelectionPoint::getRect() const {
69 QRect r(0,0,SELSIZE,SELSIZE);
70 r.moveCenter(point);
71 return r;
72 }
73
cursor()74 QCursor SelectionPoint::cursor() {
75 return _cursor;
76 }
77
setCursor(QCursor c)78 void SelectionPoint::setCursor(QCursor c) {
79 _cursor = c;
80 }
81
82
draw(QPainter * p,double scalex)83 void SelectionPoint::draw(QPainter* p, double scalex) {
84 QColor brushColor;
85
86 switch (state) {
87 case Normal:
88 brushColor = Qt::white;
89 break;
90 case HighLighted:
91 brushColor = Qt::green;
92 break;
93 case AboutToRemove:
94 brushColor = Qt::red;
95 break;
96 case Inactive:
97 brushColor = Qt::gray;
98 break;
99 }
100
101 QPoint scaledCenter((int)(point.x()*scalex),
102 (int)(point.y()*scalex));
103
104 if (state == HighLighted || state == AboutToRemove) {
105 QRect r2(0,0,SELSIZE+4,SELSIZE+4);
106
107 r2.moveCenter(scaledCenter);
108 QColor color(brushColor);
109 color.setAlpha(100);
110 p->setPen(QPen(color,4,Qt::SolidLine));
111 p->setBrush(Qt::NoBrush);
112 p->drawRect(r2);
113
114 }
115
116 // brushColor.setAlpha(230);
117 brushColor.setAlpha(200);
118 p->setBrush(QBrush(brushColor,Qt::SolidPattern));
119
120 QColor penColor = Qt::black;
121 penColor.setAlpha(120);
122 QPen pen(penColor, 2, Qt::SolidLine);
123
124 QRect r(0,0,SELSIZE,SELSIZE);
125 r.moveCenter( scaledCenter );
126
127 p->setPen(pen);
128 p->drawRect(r);
129
130
131 }
132
133
134 bool Area::highlightArea;
135 bool Area::showAlt;
136
137
Area()138 Area::Area()
139 {
140 _finished=false;
141 _isSelected=false;
142 _name=i18n("noname");
143 _listViewItem = nullptr;
144 currentHighlighted=-1;
145 _type=Area::None;
146 }
147
clone() const148 Area* Area::clone() const
149 {
150 Area* areaClone = new Area();
151 areaClone->setArea( *this );
152 return areaClone;
153 }
154
coords() const155 QPolygon Area::coords() const {
156 return _coords;
157 }
158
getHTMLAttributes() const159 QString Area::getHTMLAttributes() const
160 {
161 QString retStr="";
162
163 AttributeIterator it = attributeIterator();
164 while (it.hasNext())
165 {
166 it.next();
167 retStr+=it.key()+"=\""+it.value()+"\" ";
168 }
169
170 return retStr;
171 }
172
resetSelectionPointState()173 void Area::resetSelectionPointState() {
174 setSelectionPointStates(SelectionPoint::Normal);
175 }
176
setSelectionPointStates(SelectionPoint::State st)177 void Area::setSelectionPointStates(SelectionPoint::State st) {
178 for (int i=0;i<_selectionPoints.size();i++) {
179 _selectionPoints.at(i)->setState(st);
180 }
181 }
182
183
184
185
deleteSelectionPoints()186 void Area::deleteSelectionPoints() {
187 for (int i=0;i<_selectionPoints.size();i++) {
188 delete _selectionPoints.at(i);
189 }
190 _selectionPoints.clear();
191 }
192
~Area()193 Area::~Area() {
194 deleteSelectionPoints();
195 }
196
contains(const QPoint &) const197 bool Area::contains(const QPoint &) const {
198 return false;
199 }
200
getHTMLCode() const201 QString Area::getHTMLCode() const {
202 return "";
203 }
204
attribute(const QString & name) const205 QString Area::attribute(const QString & name) const
206 {
207 return _attributes[name.toLower()];
208 }
209
setAttribute(const QString & name,const QString & value)210 void Area::setAttribute(const QString & name, const QString & value)
211 {
212 _attributes.insert(name.toLower(), value);
213 if (value.isEmpty())
214 _attributes.remove(name.toLower());
215 }
216
attributeIterator() const217 AttributeIterator Area::attributeIterator() const
218 {
219 return AttributeIterator(_attributes);
220 }
221
setCoords(const QString &)222 bool Area::setCoords(const QString &) {
223 return true;
224 }
225
moveSelectionPoint(SelectionPoint *,const QPoint &)226 void Area::moveSelectionPoint(SelectionPoint*, const QPoint &)
227 {}
228
229 // Default implementation; is specified by subclasses
coordsToString() const230 QString Area::coordsToString() const
231 {
232 return "";
233 }
234
235
type() const236 Area::ShapeType Area::type() const {
237 return _type;
238 }
239
setArea(const Area & copy)240 void Area::setArea(const Area & copy)
241 {
242 deleteSelectionPoints();
243 _coords.clear();
244 _coords += copy.coords();
245 currentHighlighted=-1;
246
247 SelectionPointList points = copy.selectionPoints();
248 for (int i=0; i<points.size(); i++) {
249 SelectionPoint* np =
250 new SelectionPoint(points.at(i)->getPoint(),points.at(i)->cursor());
251 _selectionPoints.append(np);
252 }
253
254 _finished=copy.finished();
255 _isSelected=copy.isSelected();
256 _rect = copy.rect();
257
258 AttributeIterator it = copy.attributeIterator();
259 while (it.hasNext()) {
260 it.next();
261 setAttribute(it.key(),it.value());
262 }
263
264 setMoving(copy.isMoving());
265 }
266
setFinished(bool b,bool)267 void Area::setFinished(bool b, bool ) {
268 _finished=b;
269 }
270
271
setListViewItem(QTreeWidgetItem * item)272 void Area::setListViewItem(QTreeWidgetItem* item) {
273 _listViewItem=item;
274 }
275
deleteListViewItem()276 void Area::deleteListViewItem()
277 {
278 delete _listViewItem;
279 _listViewItem = nullptr;
280 }
281
282
setRect(const QRect & r)283 void Area::setRect(const QRect & r)
284 {
285 _rect=r;
286 updateSelectionPoints();
287 }
288
rect() const289 QRect Area::rect() const {
290 return _rect;
291 }
292
setMoving(bool b)293 void Area::setMoving(bool b) {
294 _isMoving=b;
295 }
296
297
moveBy(int dx,int dy)298 void Area::moveBy(int dx, int dy) {
299 _rect.translate(dx,dy);
300 _coords.translate(dx,dy);
301
302 for (int i=0;i < _selectionPoints.size(); i++) {
303 _selectionPoints.at(i)->translate(dx,dy);
304 }
305 }
306
307
moveTo(int x,int y)308 void Area::moveTo(int x, int y) {
309 int dx = x-rect().left();
310 int dy = y-rect().top();
311 moveBy(dx,dy);
312 }
313
countSelectionPoints() const314 int Area::countSelectionPoints() const
315 {
316 return selectionPoints().size();
317 }
318
addCoord(const QPoint & p)319 int Area::addCoord(const QPoint & p)
320 {
321 _coords.resize(_coords.size()+1);
322 _coords.setPoint(_coords.size()-1,p);
323 _selectionPoints.append(new SelectionPoint(p,QCursor(Qt::PointingHandCursor)));
324 setRect(_coords.boundingRect());
325
326 return _coords.size()-1;
327 }
328
insertCoord(int pos,const QPoint & p)329 void Area::insertCoord(int pos, const QPoint & p)
330 {
331 _coords.resize(_coords.size()+1);
332
333
334 for (int i=_coords.size()-1;i>pos;i--) {
335 _coords.setPoint(i,_coords.point(i-1));
336 }
337 _coords.setPoint(pos, p);
338
339 _selectionPoints.insert(pos,new SelectionPoint(p,QCursor(Qt::PointingHandCursor)));
340 setRect(_coords.boundingRect());
341 }
342
removeCoord(int pos)343 void Area::removeCoord(int pos) {
344
345 int count =_coords.size();
346
347 if (count<4){
348 qCDebug(KIMAGEMAPEDITOR_LOG) << "Danger : trying to remove coordinate from Area with less than 4 coordinates !";
349 return;
350 }
351
352 for (int i=pos;i<(count-1);i++)
353 _coords.setPoint(i, _coords.point(i+1));
354
355 _coords.resize(count-1);
356 delete _selectionPoints.takeAt(pos);
357 setRect(_coords.boundingRect());
358 }
359
removeSelectionPoint(SelectionPoint * p)360 bool Area::removeSelectionPoint(SelectionPoint * p)
361 {
362 if (_selectionPoints.contains(p))
363 {
364 removeCoord(_selectionPoints.indexOf(p));
365 return true;
366 }
367
368 return false;
369 }
370
371
moveCoord(int pos,const QPoint & p)372 void Area::moveCoord(int pos, const QPoint & p) {
373 _coords.setPoint(pos,p);
374 _selectionPoints.at(pos)->setPoint(p);
375 setRect(_coords.boundingRect());
376 }
377
setSelected(bool b)378 void Area::setSelected(bool b)
379 {
380 _isSelected=b;
381 if (_listViewItem) {
382 _listViewItem->setSelected(b);
383 }
384 }
385
highlightSelectionPoint(int number)386 void Area::highlightSelectionPoint(int number){
387 currentHighlighted=number;
388 }
389
selectionRect() const390 QRect Area::selectionRect() const {
391 QRect r = rect();
392 r.translate(-SELSIZE*2,-SELSIZE*2);
393 r.setSize(r.size()+QSize(SELSIZE*4,SELSIZE*4));
394
395 return r;
396 }
397
setPenAndBrush(QPainter * p)398 void Area::setPenAndBrush(QPainter* p) {
399 QBrush brush(Qt::NoBrush);
400 if (highlightArea) {
401 QColor back = Qt::white;
402 back.setAlpha(80);
403 brush = QBrush(back,Qt::SolidPattern);
404 }
405
406 p->setBrush(brush);
407
408 QColor front = Qt::white;
409 front.setAlpha(200);
410 p->setPen(QPen(front,1));
411 }
412
413
drawAlt(QPainter * p)414 void Area::drawAlt(QPainter* p)
415 {
416 double x,y;
417
418 const double scalex = p->transform().m11();
419 // double scaley = p.matrix().m12();
420
421 const QTransform oldTransform = p->transform();
422
423 p->setTransform(QTransform(1,oldTransform.m12(), oldTransform.m21(), 1, oldTransform.dx(), oldTransform.dy() ));
424
425 x = (rect().x()+rect().width()/2)*scalex;
426 y = (rect().y()+rect().height()/2)*scalex;
427
428 const QFontMetrics metrics = p->fontMetrics();
429
430 const int w = metrics.boundingRect(attribute("alt")).width();
431 x -= w/2;
432 y += metrics.height()/4;
433
434
435
436 if (highlightArea) {
437 p->setPen(Qt::black);
438 } else {
439 p->setPen(QPen(QColor("white"),1));
440 }
441
442 p->drawText(myround(x),myround(y),attribute("alt"));
443
444 p->setTransform(oldTransform);
445 }
446
draw(QPainter * p)447 void Area::draw(QPainter * p)
448 {
449
450 // Only draw the selection points at base class
451 // the rest is done in the derived classes
452 if (_isSelected) {
453 // We do not want to have the selection points
454 // scaled, so calculate the unscaled version
455 const double scalex = p->transform().m11();
456 const QTransform oldTransform = p->transform();
457 p->setTransform(QTransform(1,oldTransform.m12(),
458 oldTransform.m21(), 1,
459 oldTransform.dx(),
460 oldTransform.dy() ));
461
462 for (int i=0; i<_selectionPoints.size(); i++) {
463 _selectionPoints.at(i)->draw(p,scalex);
464 }
465 p->setTransform(oldTransform);
466 }
467
468 if (showAlt) {
469 drawAlt(p);
470 }
471
472 }
473
onSelectionPoint(const QPoint & p,double zoom) const474 SelectionPoint* Area::onSelectionPoint(const QPoint & p, double zoom) const
475 {
476
477 for (int i=0; i<_selectionPoints.size(); i++) {
478 SelectionPoint* sp = _selectionPoints.at(i);
479
480 QRect r = sp->getRect();
481
482 r.moveCenter(sp->getPoint()*zoom);
483
484 if (r.contains(p))
485 {
486 return sp;
487 }
488 }
489
490 return nullptr;
491 }
492
493
494
495
496 /**
497 * returns only the part of the image which is
498 * covered by the area
499 */
cutOut(const QImage & image)500 QPixmap Area::cutOut(const QImage & image)
501 {
502 if ( 0>=rect().width() ||
503 0>=rect().height() ||
504 !rect().intersects(image.rect()) )
505 {
506 QPixmap dummyPix(10,10);
507 dummyPix.fill();
508 return dummyPix;
509 }
510
511 // Get the mask from the subclasses
512 QBitmap mask=getMask();
513
514 // The rectangle which is part of the image
515 QRect partOfImage=rect();
516 QRect partOfMask(0,0,mask.width(),mask.height());
517
518
519 // If the area is outside of the image make the
520 // preview smaller
521 if ( (rect().x()+rect().width()) > image.width() ) {
522 partOfImage.setWidth( image.width()-rect().x() );
523 partOfMask.setWidth( image.width()-rect().x() );
524 }
525
526 if ( (rect().x() < 0) ) {
527 partOfImage.setX(0);
528 partOfMask.setX(myabs(rect().x()));
529 }
530
531 if ( (rect().y()+rect().height()) > image.height() ) {
532 partOfImage.setHeight( image.height()-rect().y() );
533 partOfMask.setHeight ( image.height()-rect().y() );
534 }
535
536 if ( (rect().y() < 0) ) {
537 partOfImage.setY(0);
538 partOfMask.setY(myabs(rect().y()));
539 }
540
541 QImage tempImage=mask.toImage().copy(partOfMask);
542 mask = QPixmap::fromImage(tempImage);
543
544 // partOfImage = partOfImage.normalize();
545 QImage cut=image.copy(partOfImage);
546
547 QPixmap pix;
548
549 // partOfMask = partOfMask.normalize();
550 if (!partOfMask.isValid())
551 qCDebug(KIMAGEMAPEDITOR_LOG) << "PartofMask not valid : " << partOfMask.x() << "," << partOfMask.y() << ","
552 << partOfMask.width() << "," << partOfMask.height() << ",";
553
554 /*
555 QBitmap mask2(partOfMask.width(), partOfMask.height());
556 QPainter p4(&mask2);
557 p4.drawPixmap( QPoint(0,0) ,mask,partOfMask);
558 p4.flush();
559 p4.end();
560 */
561
562 pix = QPixmap::fromImage(cut);
563
564 // setHighlightedPixmap(cut, mask);
565
566 QPixmap retPix(pix.width(),pix.height());
567 QPainter p3(&retPix);
568
569 // if transparent image fill the background
570 // with gimp-like rectangles
571 if (!pix.mask().isNull()) {
572 QPixmap backPix(32,32);
573
574 // Gimp like transparent rectangle
575 QPainter p2(&backPix);
576 p2.fillRect(0,0,32,32,QColor(156,149,156));
577 p2.fillRect(0,16,16,16,QColor(98,105,98));
578 p2.fillRect(16,0,16,16,QColor(98,105,98));
579
580 p3.setPen(QPen());
581 p3.fillRect(0,0,pix.width(),pix.height(),QBrush(QColor("black"),backPix));
582 }
583
584
585 p3.drawPixmap(QPoint(0,0),pix);
586 p3.end();
587 retPix.setMask(mask);
588
589 return retPix;
590 }
591
getMask() const592 QBitmap Area::getMask() const
593 {
594 QBitmap b;
595 return b;
596 }
597
598 /********************************************************************
599 * RECTANGLE
600 *******************************************************************/
601
602
RectArea()603 RectArea::RectArea()
604 : Area()
605 {
606 _type=Area::Rectangle;
607 QPoint p(0,0);
608 _selectionPoints.append(new SelectionPoint(p,Qt::SizeFDiagCursor));
609 _selectionPoints.append(new SelectionPoint(p,Qt::SizeBDiagCursor));
610 _selectionPoints.append(new SelectionPoint(p,Qt::SizeBDiagCursor));
611 _selectionPoints.append(new SelectionPoint(p,Qt::SizeFDiagCursor));
612 _selectionPoints.append(new SelectionPoint(p,Qt::SizeVerCursor));
613 _selectionPoints.append(new SelectionPoint(p,Qt::SizeHorCursor));
614 _selectionPoints.append(new SelectionPoint(p,Qt::SizeVerCursor));
615 _selectionPoints.append(new SelectionPoint(p,Qt::SizeHorCursor));
616 }
617
~RectArea()618 RectArea::~RectArea() {
619 }
620
clone() const621 Area* RectArea::clone() const
622 {
623 Area* areaClone = new RectArea();
624 areaClone->setArea( *this );
625 return areaClone;
626 }
627
draw(QPainter * p)628 void RectArea::draw(QPainter * p)
629 {
630 setPenAndBrush(p);
631
632 QRect r(rect());
633 r.setWidth(r.width()+1);
634 r.setHeight(r.height()+1);
635 p->drawRect(r);
636
637 Area::draw(p);
638 }
639
getMask() const640 QBitmap RectArea::getMask() const
641 {
642 QBitmap mask(rect().width(),rect().height());
643
644 mask.fill(Qt::color0);
645 QPainter p(&mask);
646 p.setBackground(QBrush(Qt::color0));
647 p.setPen(Qt::color1);
648 p.setBrush(Qt::color1);
649 mask.fill(Qt::color1);
650 p.end();
651
652 return mask;
653 }
654
coordsToString() const655 QString RectArea::coordsToString() const
656 {
657 QString retStr=QString("%1,%2,%3,%4")
658 .arg(rect().left())
659 .arg(rect().top())
660 .arg(rect().right())
661 .arg(rect().bottom());
662
663 return retStr;
664 }
665
contains(const QPoint & p) const666 bool RectArea::contains(const QPoint & p) const{
667 return rect().contains(p);
668 }
669
moveSelectionPoint(SelectionPoint * selectionPoint,const QPoint & p)670 void RectArea::moveSelectionPoint(SelectionPoint* selectionPoint, const QPoint & p)
671 {
672 selectionPoint->setPoint(p);
673 int i = _selectionPoints.indexOf(selectionPoint);
674
675 QRect r2(_rect);
676 switch (i) {
677 case 0 :
678 _rect.setLeft(p.x());
679 _rect.setTop(p.y());
680 break;
681 case 1 :
682 _rect.setRight(p.x());
683 _rect.setTop(p.y());
684 break;
685 case 2 :
686 _rect.setLeft(p.x());
687 _rect.setBottom(p.y());
688 break;
689 case 3 :
690 _rect.setRight(p.x());
691 _rect.setBottom(p.y());
692 break;
693 case 4 : // top line
694 _rect.setTop(p.y());
695 break;
696 case 5 : // right line
697 _rect.setRight(p.x());
698 break;
699 case 6 : // bottom
700 _rect.setBottom(p.y());
701 break;
702 case 7 : // left
703 _rect.setLeft(p.x());
704 break;
705
706 }
707 if (! _rect.isValid())
708 _rect=r2;
709
710 updateSelectionPoints();
711 }
712
updateSelectionPoints()713 void RectArea::updateSelectionPoints()
714 {
715 int d = 2;
716 QRect r(_rect);
717 r.adjust(0,0,1,1);
718 int xmid = r.left()+(r.width()/d);
719 int ymid = r.top()+(r.height()/d);
720
721
722 _selectionPoints[0]->setPoint(r.topLeft());
723 _selectionPoints[1]->setPoint(r.topRight());
724 _selectionPoints[2]->setPoint(r.bottomLeft());
725 _selectionPoints[3]->setPoint(r.bottomRight());
726 _selectionPoints[4]->setPoint(QPoint(xmid,r.top()));
727 _selectionPoints[5]->setPoint(QPoint(r.right(),ymid));
728 _selectionPoints[6]->setPoint(QPoint(xmid,r.bottom()));
729 _selectionPoints[7]->setPoint(QPoint(r.left(),ymid));
730 }
731
setCoords(const QString & s)732 bool RectArea::setCoords(const QString & s)
733 {
734 _finished=true;
735
736 const QStringList list = s.split(',');
737 QRect r;
738 bool ok=true;
739 QStringList::ConstIterator it = list.begin();
740 r.setLeft((*it).toInt(&ok,10));it++;
741 r.setTop((*it).toInt(&ok,10));it++;
742 r.setRight((*it).toInt(&ok,10));it++;
743 r.setBottom((*it).toInt(&ok,10));
744 if (ok) {
745 setRect(r);
746 return true;
747 } else {
748 return false;
749 }
750 }
751
getHTMLCode() const752 QString RectArea::getHTMLCode() const {
753 QString retStr;
754 retStr+="<area ";
755 retStr+="shape=\"rect\" ";
756
757 retStr+=getHTMLAttributes();
758
759 retStr+="coords=\""+coordsToString()+"\" ";
760 retStr+="/>";
761 return retStr;
762
763 }
764
765 /********************************************************************
766 * CIRCLE
767 *******************************************************************/
768
769
CircleArea()770 CircleArea::CircleArea()
771 : Area()
772 {
773 _type = Area::Circle;
774 QPoint p(0,0);
775 _selectionPoints.append(new SelectionPoint(p,Qt::SizeFDiagCursor));
776 _selectionPoints.append(new SelectionPoint(p,Qt::SizeBDiagCursor));
777 _selectionPoints.append(new SelectionPoint(p,Qt::SizeBDiagCursor));
778 _selectionPoints.append(new SelectionPoint(p,Qt::SizeFDiagCursor));
779 }
780
~CircleArea()781 CircleArea::~CircleArea() {
782 }
783
clone() const784 Area* CircleArea::clone() const
785 {
786 Area* areaClone = new CircleArea();
787 areaClone->setArea( *this );
788 return areaClone;
789 }
790
draw(QPainter * p)791 void CircleArea::draw(QPainter * p)
792 {
793 setPenAndBrush(p);
794
795 QRect r(_rect);
796 r.setWidth(r.width()+1);
797 r.setHeight(r.height()+1);
798 p->drawEllipse(r);
799
800 Area::draw(p);
801 }
802
getMask() const803 QBitmap CircleArea::getMask() const
804 {
805 QBitmap mask(_rect.width(),_rect.height());
806
807 mask.fill(Qt::color0);
808 QPainter p(&mask);
809 p.setBackground(QBrush(Qt::color0));
810 p.setPen(Qt::color1);
811 p.setBrush(Qt::color1);
812 p.drawPie(QRect(0,0,_rect.width(),_rect.height()),0,5760);
813 p.end();
814
815
816 return mask;
817
818 }
819
coordsToString() const820 QString CircleArea::coordsToString() const
821 {
822 QString retStr=QString("%1,%2,%3")
823 .arg(_rect.center().x())
824 .arg(_rect.center().y())
825 .arg(_rect.width()/2);
826
827 return retStr;
828 }
829
contains(const QPoint & p) const830 bool CircleArea::contains(const QPoint & p) const
831 {
832 QRegion r(_rect,QRegion::Ellipse);
833 return r.contains(p);
834 }
835
moveSelectionPoint(SelectionPoint * selectionPoint,const QPoint & p)836 void CircleArea::moveSelectionPoint(SelectionPoint* selectionPoint, const QPoint & p)
837 {
838 selectionPoint->setPoint(p);
839
840 int i = _selectionPoints.indexOf(selectionPoint);
841
842 // The code below really sucks, but I have no better idea.
843 // it only makes sure that the circle is perfectly round
844
845 QPoint newPoint;
846 int diff=myabs(p.x()-_rect.center().x());
847 if (myabs(p.y()-_rect.center().y())>diff)
848 diff=myabs(p.y()-_rect.center().y());
849
850 newPoint.setX( p.x()-_rect.center().x()<0
851 ? _rect.center().x()-diff
852 : _rect.center().x()+diff);
853
854 newPoint.setY( p.y()-_rect.center().y()<0
855 ? _rect.center().y()-diff
856 : _rect.center().y()+diff);
857
858 switch (i) {
859 case 0 : if (newPoint.x() < _rect.center().x() &&
860 newPoint.y() < _rect.center().y())
861 {
862 _rect.setLeft(newPoint.x());
863 _rect.setTop(newPoint.y());
864 }
865 break;
866 case 1 : if (newPoint.x() > _rect.center().x() &&
867 newPoint.y() < _rect.center().y())
868 {
869 _rect.setRight(newPoint.x());
870 _rect.setTop(newPoint.y());
871 }
872 break;
873 case 2 : if (newPoint.x() < _rect.center().x() &&
874 newPoint.y() > _rect.center().y())
875 {
876 _rect.setLeft(newPoint.x());
877 _rect.setBottom(newPoint.y());
878 }
879 break;
880 case 3 : if (newPoint.x() > _rect.center().x() &&
881 newPoint.y() > _rect.center().y())
882 {
883 _rect.setRight(newPoint.x());
884 _rect.setBottom(newPoint.y());
885 }
886 break;
887 }
888
889
890
891 updateSelectionPoints();
892
893 }
894
setRect(const QRect & r)895 void CircleArea::setRect(const QRect & r)
896 {
897 QRect r2 = r;
898 if ( r2.height() != r2.width() )
899 r2.setHeight( r2.width() );
900
901 Area::setRect(r2);
902 }
903
904
updateSelectionPoints()905 void CircleArea::updateSelectionPoints()
906 {
907 _selectionPoints[0]->setPoint(_rect.topLeft());
908 _selectionPoints[1]->setPoint(_rect.topRight());
909 _selectionPoints[2]->setPoint(_rect.bottomLeft());
910 _selectionPoints[3]->setPoint(_rect.bottomRight());
911 }
912
setCoords(const QString & s)913 bool CircleArea::setCoords(const QString & s)
914 {
915 _finished=true;
916 const QStringList list = s.split(',');
917 bool ok=true;
918 QStringList::ConstIterator it = list.begin();
919 int x=(*it).toInt(&ok,10);it++;
920 int y=(*it).toInt(&ok,10);it++;
921 int rad=(*it).toInt(&ok,10);
922 if (!ok) return false;
923 QRect r;
924 r.setWidth(rad*2);
925 r.setHeight(rad*2);
926 r.moveCenter(QPoint(x,y));
927 setRect(r);
928 return true;
929 }
930
getHTMLCode() const931 QString CircleArea::getHTMLCode() const {
932 QString retStr;
933 retStr+="<area ";
934 retStr+="shape=\"circle\" ";
935
936 retStr+=getHTMLAttributes();
937
938 retStr+="coords=\""+coordsToString()+"\" ";
939 retStr+="/>";
940 return retStr;
941
942 }
943
944
945 /********************************************************************
946 * POLYGON
947 *******************************************************************/
948
949
PolyArea()950 PolyArea::PolyArea()
951 : Area()
952 {
953 _type = Area::Polygon;
954 }
955
~PolyArea()956 PolyArea::~PolyArea() {
957 }
958
clone() const959 Area* PolyArea::clone() const
960 {
961 Area* areaClone = new PolyArea();
962 areaClone->setArea( *this );
963 return areaClone;
964 }
965
draw(QPainter * p)966 void PolyArea::draw(QPainter * p)
967 {
968 setPenAndBrush(p);
969
970 if (_finished)
971 p->drawPolygon( _coords.constData(),_coords.count());
972 else {
973 p->drawPolyline(_coords.constData(),_coords.count());
974 }
975
976 Area::draw(p);
977 }
978
getMask() const979 QBitmap PolyArea::getMask() const
980 {
981 QBitmap mask(_rect.width(),_rect.height());
982
983 mask.fill(Qt::color0);
984 QPainter p(&mask);
985 p.setBackground(QBrush(Qt::color0));
986 p.setPen(Qt::color1);
987 p.setBrush(Qt::color1);
988 p.setClipping(true);
989 QRegion r(_coords);
990 r.translate(-_rect.left(),-_rect.top());
991 p.setClipRegion(r);
992 p.fillRect(QRect(0,0,_rect.width(),_rect.height()),Qt::color1);
993 p.end();
994
995 return mask;
996 }
997
coordsToString() const998 QString PolyArea::coordsToString() const
999 {
1000 QString retStr;
1001
1002 for (int i=0;i<_coords.count();i++) {
1003 retStr.append(QString("%1,%2,")
1004 .arg(_coords.point(i).x())
1005 .arg(_coords.point(i).y()));
1006 }
1007
1008 retStr.remove(retStr.length()-1,1);
1009
1010 return retStr;
1011 }
1012
distance(const QPoint & p1,const QPoint & p2)1013 int PolyArea::distance(const QPoint &p1, const QPoint &p2)
1014 {
1015 QPoint temp = p1-p2;
1016 return temp.manhattanLength();
1017 }
1018
isBetween(const QPoint & p,const QPoint & p1,const QPoint & p2)1019 bool PolyArea::isBetween(const QPoint &p, const QPoint &p1, const QPoint &p2)
1020 {
1021 int dist = distance(p,p1)+distance(p,p2)-distance(p1,p2);
1022
1023 if (myabs(dist)<1)
1024 return true;
1025 else
1026 return false;
1027 }
1028
simplifyCoords()1029 void PolyArea::simplifyCoords()
1030 {
1031 if (_coords.size()<4)
1032 return;
1033
1034 QPoint p = _coords.point(0) - _coords.point(1);
1035
1036 int i = 1;
1037
1038
1039 while( (i<_coords.size()) && (_coords.size() > 3) )
1040 {
1041 p = _coords.point(i-1) - _coords.point(i);
1042
1043 if (p.manhattanLength() < 3)
1044 removeCoord(i);
1045 else
1046 i++;
1047 }
1048
1049 p = _coords.point(0) - _coords.point(1);
1050
1051 double angle2;
1052 double angle1;
1053
1054 if (p.y()==0)
1055 angle1 = 1000000000;
1056 else
1057 angle1 = (double) p.x() / (double) p.y();
1058
1059 i=2;
1060
1061 while( (i<_coords.size()) && (_coords.size() > 3) )
1062 {
1063 p = _coords.point(i-1) - _coords.point(i);
1064
1065 if (p.y()==0)
1066 angle2 = 1000000000;
1067 else
1068 angle2 = (double) p.x() / (double) p.y();
1069
1070 if ( angle2==angle1 )
1071 {
1072 qCDebug(KIMAGEMAPEDITOR_LOG) << "removing " << i-1;
1073 removeCoord(i-1);
1074 }
1075 else
1076 {
1077 i++;
1078 qCDebug(KIMAGEMAPEDITOR_LOG) << "skipping " << i-1 << " cause " << angle1 << "!= " << angle2;
1079 angle1 = angle2;
1080
1081 }
1082
1083 }
1084
1085
1086
1087 }
1088
1089
addCoord(const QPoint & p)1090 int PolyArea::addCoord(const QPoint & p)
1091 {
1092 if (_coords.size()<3)
1093 {
1094 return Area::addCoord(p);
1095 }
1096
1097 if (_coords.point(_coords.size()-1) == p)
1098 {
1099 qCDebug(KIMAGEMAPEDITOR_LOG) << "equal Point added";
1100 return -1;
1101
1102 }
1103
1104 int n=_coords.size();
1105
1106 // QPoint temp = p-_coords.point(0);
1107 int nearest = 0;
1108 int olddist = distance(p,_coords.point(0));
1109 int mindiff = 999999999;
1110
1111 // find the two points, which are the nearest one to the new point
1112 for (int i=1; i <= n; i++)
1113 {
1114 int dist = distance(p,_coords.point(i%n));
1115 int dist2 = distance(_coords.point(i-1),_coords.point(i%n));
1116 int diff = myabs(dist+olddist-dist2);
1117 if ( diff<mindiff )
1118 {
1119 mindiff = diff;
1120 nearest = i%n;
1121 }
1122 olddist=dist;
1123 }
1124
1125 insertCoord(nearest, p);
1126
1127 return nearest;
1128
1129 }
1130
contains(const QPoint & p) const1131 bool PolyArea::contains(const QPoint & p) const
1132 {
1133 // A line can't contain a point
1134 if (_coords.count() >2 ) {
1135 QRegion r(_coords);
1136 return r.contains(p);
1137 }
1138 else
1139 return false;
1140 }
1141
moveSelectionPoint(SelectionPoint * selectionPoint,const QPoint & p)1142 void PolyArea::moveSelectionPoint(SelectionPoint* selectionPoint, const QPoint & p)
1143 {
1144 selectionPoint->setPoint(p);
1145
1146 int i = _selectionPoints.indexOf(selectionPoint);
1147 _coords.setPoint(i,p);
1148 _rect=_coords.boundingRect();
1149 }
1150
updateSelectionPoints()1151 void PolyArea::updateSelectionPoints()
1152 {
1153 for (int i = 0; i < _selectionPoints.size(); ++i) {
1154 _selectionPoints.at(i)->setPoint(_coords.point(i));
1155 }
1156 }
1157
setCoords(const QString & s)1158 bool PolyArea::setCoords(const QString & s)
1159 {
1160 _finished=true;
1161 const QStringList list = s.split(',');
1162 _coords.clear();
1163 _selectionPoints.clear();
1164
1165 for (QStringList::ConstIterator it = list.begin(); it !=list.end(); ++it)
1166 {
1167 bool ok=true;
1168 int newXCoord=(*it).toInt(&ok,10);
1169 if (!ok) return false;
1170 it++;
1171 if (it==list.end()) break;
1172 int newYCoord=(*it).toInt(&ok,10);
1173 if (!ok) return false;
1174 insertCoord(_coords.size(), QPoint(newXCoord,newYCoord));
1175 }
1176
1177 return true;
1178
1179 }
1180
getHTMLCode() const1181 QString PolyArea::getHTMLCode() const {
1182 QString retStr;
1183 retStr+="<area ";
1184 retStr+="shape=\"poly\" ";
1185
1186 retStr+=getHTMLAttributes();
1187
1188 retStr+="coords=\""+coordsToString()+"\" ";
1189 retStr+="/>";
1190 return retStr;
1191
1192 }
1193
setFinished(bool b,bool removeLast=true)1194 void PolyArea::setFinished(bool b, bool removeLast = true)
1195 {
1196 // The last Point is the same as the first
1197 // so delete it
1198 if (b && removeLast) {
1199 _coords.resize(_coords.size()-1);
1200 _selectionPoints.removeLast();
1201 }
1202
1203 _finished = b;
1204 }
1205
selectionRect() const1206 QRect PolyArea::selectionRect() const
1207 {
1208 QRect r = _rect;
1209
1210 r.translate(-10,-10);
1211 r.setSize(r.size()+QSize(21,21));
1212
1213 return r;
1214 }
1215
1216
1217
1218 /********************************************************************
1219 * DEFAULT
1220 *******************************************************************/
1221
1222
DefaultArea()1223 DefaultArea::DefaultArea()
1224 : Area()
1225 {
1226 _type=Area::Default;
1227 }
1228
~DefaultArea()1229 DefaultArea::~DefaultArea() {
1230 }
1231
clone() const1232 Area* DefaultArea::clone() const
1233 {
1234 Area* areaClone = new DefaultArea();
1235 areaClone->setArea( *this );
1236 return areaClone;
1237 }
1238
draw(QPainter *)1239 void DefaultArea::draw(QPainter *)
1240 {}
1241
1242
getHTMLCode() const1243 QString DefaultArea::getHTMLCode() const {
1244 QString retStr;
1245 retStr+="<area ";
1246 retStr+="shape=\"default\" ";
1247
1248 retStr+=getHTMLAttributes();
1249
1250 retStr+="/>";
1251 return retStr;
1252
1253 }
1254
1255
1256 /********************************************************************
1257 * AreaSelection
1258 *******************************************************************/
1259
AreaSelection()1260 AreaSelection::AreaSelection()
1261 : Area()
1262 {
1263 _areas = new AreaList();
1264 _name = "Selection";
1265 invalidate();
1266 }
1267
~AreaSelection()1268 AreaSelection::~AreaSelection() {
1269 delete _areas;
1270 }
1271
clone() const1272 Area* AreaSelection::clone() const
1273 {
1274 AreaSelection* areaClone = new AreaSelection();
1275
1276 // we want a deep copy of the Areas
1277 AreaListIterator it=getAreaListIterator();
1278 while (it.hasNext()) {
1279 areaClone->add( it.next()->clone() );
1280 }
1281
1282 return areaClone;
1283 }
1284
1285
add(Area * a)1286 void AreaSelection::add(Area *a)
1287 {
1288 // if a selection of areas was added get the areas of it
1289 AreaSelection *selection = nullptr;
1290 if ( (selection = dynamic_cast <AreaSelection*> ( a ) ) ) {
1291 AreaList list = selection->getAreaList();
1292 Area* area;
1293 foreach(area,list) {
1294 if ( !_areas->contains( area )) {
1295 _areas->append( area ); // Must come before area->setSelected
1296 area->setSelected( true );
1297 }
1298 }
1299 } else {
1300 if ( !_areas->contains( a )) {
1301 _areas->append( a ); // Must come before a->setSelected
1302 a->setSelected( true );
1303 }
1304 }
1305
1306 invalidate();
1307 }
1308
1309
setSelectionPointStates(SelectionPoint::State st)1310 void AreaSelection::setSelectionPointStates(SelectionPoint::State st) {
1311 AreaListIterator it=getAreaListIterator();
1312 while(it.hasNext()) {
1313 it.next()->setSelectionPointStates( st );
1314 }
1315 }
1316
updateSelectionPointStates()1317 void AreaSelection::updateSelectionPointStates() {
1318 SelectionPoint::State st = SelectionPoint::Normal;
1319
1320 if (_areas->count() > 1)
1321 st = SelectionPoint::Inactive;
1322
1323 setSelectionPointStates(st);
1324 }
1325
1326
remove(Area * a)1327 void AreaSelection::remove(Area *a)
1328 {
1329 if (!_areas->contains(a))
1330 return;
1331
1332 a->setSelected( false );
1333 _areas->removeAt(_areas->indexOf(a));
1334 invalidate();
1335 }
1336
reset()1337 void AreaSelection::reset()
1338 {
1339 AreaListIterator it=getAreaListIterator();
1340 while (it.hasNext()) {
1341 it.next()->setSelected( false );
1342 }
1343
1344 _areas->clear();
1345 invalidate();
1346 }
1347
contains(const QPoint & p) const1348 bool AreaSelection::contains(const QPoint & p) const
1349 {
1350 AreaListIterator it=getAreaListIterator();
1351 while (it.hasNext()) {
1352 if ( it.next()->contains( p ) ) {
1353 return true;
1354 }
1355 }
1356
1357 return false;
1358 }
1359
onSelectionPoint(const QPoint & p,double zoom) const1360 SelectionPoint* AreaSelection::onSelectionPoint(const QPoint & p, double zoom) const
1361 {
1362
1363 if (_areas->count() != 1)
1364 return nullptr;
1365
1366 return _areas->first()->onSelectionPoint(p,zoom);
1367 }
1368
moveSelectionPoint(SelectionPoint * selectionPoint,const QPoint & p)1369 void AreaSelection::moveSelectionPoint(SelectionPoint* selectionPoint, const QPoint & p)
1370 {
1371 // It's only possible to move a SelectionPoint if only one Area is selected
1372 if (_areas->count() != 1)
1373 return;
1374
1375 _areas->first()->moveSelectionPoint(selectionPoint,p);
1376
1377 invalidate();
1378 }
1379
1380
moveBy(int dx,int dy)1381 void AreaSelection::moveBy(int dx, int dy)
1382 {
1383 AreaListIterator it=getAreaListIterator();
1384 while (it.hasNext()) {
1385 it.next()->moveBy(dx,dy);
1386 }
1387
1388 Area::moveBy( dx, dy );
1389 invalidate();
1390 }
1391
typeString() const1392 QString AreaSelection::typeString() const
1393 {
1394 // if there is only one Area selected
1395 // show the name of that Area
1396 if ( _areas->count()==0 )
1397 return "";
1398 else if ( _areas->count()==1 )
1399 return _areas->first()->typeString();
1400 else
1401 return i18n("Number of Areas");
1402
1403 }
1404
type() const1405 Area::ShapeType AreaSelection::type() const
1406 {
1407 // if there is only one Area selected
1408 // take the type of that Area
1409 if ( _areas->count()==0 )
1410 return Area::None;
1411 else if ( _areas->count()==1 )
1412 return _areas->first()->type();
1413 else
1414 return Area::Selection;
1415 }
1416
resetSelectionPointState()1417 void AreaSelection::resetSelectionPointState() {
1418 updateSelectionPointStates();
1419 }
1420
updateSelectionPoints()1421 void AreaSelection::updateSelectionPoints()
1422 {
1423 AreaListIterator it=getAreaListIterator();
1424 while (it.hasNext()) {
1425 it.next()->updateSelectionPoints();
1426 }
1427
1428 invalidate();
1429 }
1430
1431
1432
selectionRect() const1433 QRect AreaSelection::selectionRect() const
1434 {
1435 if (!_selectionCacheValid) {
1436 _selectionCacheValid=true;
1437 QRect r;
1438 AreaListIterator it=getAreaListIterator();
1439 while (it.hasNext()) {
1440 r = r | it.next()->selectionRect();
1441 }
1442 _cachedSelectionRect=r;
1443 }
1444
1445 return _cachedSelectionRect;
1446 }
1447
count() const1448 int AreaSelection::count() const {
1449 return _areas->count();
1450 }
1451
isEmpty() const1452 bool AreaSelection::isEmpty() const
1453 {
1454 return _areas->isEmpty();
1455 }
1456
1457
getAreaList() const1458 AreaList AreaSelection::getAreaList() const {
1459 AreaList list(*_areas);
1460 return list;
1461 }
1462
getAreaListIterator() const1463 AreaListIterator AreaSelection::getAreaListIterator() const {
1464 AreaListIterator it(*_areas);
1465 return it;
1466 }
1467
setArea(const Area & copy)1468 void AreaSelection::setArea(const Area & copy)
1469 {
1470 Area *area = copy.clone();
1471 AreaSelection *selection = dynamic_cast<AreaSelection*>(area);
1472 if (selection)
1473 setAreaSelection(*selection);
1474 else {
1475 Area::setArea(copy);
1476 invalidate();
1477 }
1478 }
1479
setAreaSelection(const AreaSelection & copy)1480 void AreaSelection::setAreaSelection(const AreaSelection & copy)
1481 {
1482 AreaList* areasCopy = copy._areas;
1483
1484 if (_areas->count() != areasCopy->count())
1485 return;
1486
1487 AreaListIterator it(*_areas);
1488 AreaListIterator it2(*areasCopy);
1489 while (it.hasNext()) {
1490 it.next()->setArea(*it2.next());
1491 }
1492
1493 Area::setArea(copy);
1494 invalidate();
1495 }
1496
setAreaList(const AreaList & areas)1497 void AreaSelection::setAreaList( const AreaList & areas )
1498 {
1499 delete _areas;
1500 _areas = new AreaList(areas);
1501 invalidate();
1502 }
1503
setRect(const QRect & r)1504 void AreaSelection::setRect(const QRect & r)
1505 {
1506 if ( _areas->count()==1 )
1507 {
1508 _areas->first()->setRect(r);
1509 }
1510
1511 invalidate();
1512 _rect=rect();
1513 updateSelectionPoints();
1514 }
1515
rect() const1516 QRect AreaSelection::rect() const
1517 {
1518 if (!_rectCacheValid)
1519 {
1520 _rectCacheValid=true;
1521 QRect r;
1522 AreaListIterator it=getAreaListIterator();
1523
1524 while (it.hasNext()) {
1525 r = r | it.next()->rect();
1526 }
1527
1528 _cachedRect=r;
1529 }
1530
1531 return _cachedRect;
1532 }
1533
1534
addCoord(const QPoint & p)1535 int AreaSelection::addCoord(const QPoint & p)
1536 {
1537 if ( _areas->count()==1 )
1538 {
1539 return _areas->first()->addCoord(p);
1540 invalidate();
1541 }
1542
1543 return 0;
1544 }
1545
insertCoord(int pos,const QPoint & p)1546 void AreaSelection::insertCoord(int pos, const QPoint & p)
1547 {
1548 if ( _areas->count()==1 )
1549 {
1550 _areas->first()->insertCoord(pos, p);
1551 invalidate();
1552 }
1553 }
1554
removeCoord(int pos)1555 void AreaSelection::removeCoord(int pos)
1556 {
1557 if ( _areas->count()==1 )
1558 {
1559 _areas->first()->removeCoord(pos);
1560 invalidate();
1561 }
1562 }
1563
removeSelectionPoint(SelectionPoint * p)1564 bool AreaSelection::removeSelectionPoint(SelectionPoint* p)
1565 {
1566 bool result=false;
1567
1568 if ( _areas->count()==1 )
1569 {
1570 result = _areas->first()->removeSelectionPoint(p);
1571 invalidate();
1572 }
1573
1574 return result;
1575 }
1576
selectionPoints() const1577 const SelectionPointList & AreaSelection::selectionPoints() const
1578 {
1579 if ( _areas->count()==1 )
1580 {
1581 return _areas->first()->selectionPoints();
1582 }
1583
1584 return _selectionPoints;
1585 }
1586
1587
moveCoord(int pos,const QPoint & p)1588 void AreaSelection::moveCoord(int pos,const QPoint & p)
1589 {
1590 if ( _areas->count()==1 )
1591 {
1592 _areas->first()->moveCoord(pos,p);
1593 invalidate();
1594 }
1595 }
1596
highlightSelectionPoint(int i)1597 void AreaSelection::highlightSelectionPoint(int i)
1598 {
1599 if ( _areas->count()==1 )
1600 {
1601 _areas->first()->highlightSelectionPoint(i);
1602 invalidate();
1603 }
1604 }
1605
1606
coords() const1607 QPolygon AreaSelection::coords() const
1608 {
1609 if ( _areas->count()==1 )
1610 {
1611 return _areas->first()->coords();
1612 }
1613
1614 return Area::coords();
1615 }
1616
attribute(const QString & name) const1617 QString AreaSelection::attribute(const QString & name) const
1618 {
1619 if ( _areas->count()==1 )
1620 {
1621 return _areas->first()->attribute(name);
1622 }
1623
1624 return Area::attribute(name);
1625 }
1626
setAttribute(const QString & name,const QString & value)1627 void AreaSelection::setAttribute(const QString & name, const QString & value)
1628 {
1629 AreaListIterator it=getAreaListIterator();
1630
1631 while (it.hasNext()) {
1632 it.next()->setAttribute(name,value);
1633 }
1634
1635 Area::setAttribute(name,value);
1636 }
1637
attributeIterator() const1638 AttributeIterator AreaSelection::attributeIterator() const
1639 {
1640 if ( _areas->count()==1 )
1641 {
1642 return _areas->first()->attributeIterator();
1643 }
1644
1645 return AttributeIterator(_attributes);
1646 }
1647
setMoving(bool b)1648 void AreaSelection::setMoving(bool b)
1649 {
1650 AreaListIterator it=getAreaListIterator();
1651
1652 while (it.hasNext()) {
1653 it.next()->setMoving(b);
1654 }
1655
1656 Area::setMoving(b);
1657 }
1658
isMoving() const1659 bool AreaSelection::isMoving() const
1660 {
1661 if ( _areas->count()==1 )
1662 {
1663 return _areas->first()->isMoving();
1664 }
1665
1666 return Area::isMoving();
1667 }
1668
1669
1670 /**
1671 * Checks if an area is outside the rectangle parameter
1672 * returns false if an area has no pixel in common with the rectangle parameter
1673 **/
allAreasWithin(const QRect & r) const1674 bool AreaSelection::allAreasWithin(const QRect & r) const
1675 {
1676 if ( ! r.contains(rect()) )
1677 {
1678 AreaListIterator it=getAreaListIterator();
1679
1680 while (it.hasNext()) {
1681 if (!it.next()->rect().intersects(r))
1682 return false;
1683 }
1684 }
1685
1686 return true;
1687 }
1688
1689
draw(QPainter *)1690 void AreaSelection::draw(QPainter *)
1691 {}
1692
invalidate()1693 void AreaSelection::invalidate() {
1694 _selectionCacheValid=false;
1695 _rectCacheValid=false;
1696 updateSelectionPointStates();
1697 }
1698
1699
1700