/*************************************************************************** kimearea.cpp - description ------------------- begin : Thu Jun 14 2001 copyright : (C) 2001 by Jan Schaefer email : janschaefer@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "kimearea.h" #include "kimecommon.h" #define SELSIZE 7 bool Area::highlightArea; bool Area::showAlt; Area::Area() { _coords=new QPointArray(); _selectionPoints= new SelectionPointList(); _selectionPoints->setAutoDelete(true); _finished=false; _isSelected=false; _name=i18n("noname"); _listViewItem=0L; currentHighlighted=-1; _type=Area::None; _highlightedPixmap=0L; } Area* Area::clone() const { Area* areaClone = new Area(); areaClone->setArea( *this ); return areaClone; } QPointArray* Area::coords() const { return _coords; } QString Area::getHTMLAttributes() const { QString retStr=""; for (AttributeIterator it = firstAttribute();it!=lastAttribute();++it) { retStr+=it.key()+"=\""+it.data()+"\" "; } return retStr; } Area::~Area() { delete _coords; delete _selectionPoints; delete _highlightedPixmap; } bool Area::contains(const QPoint &) const { return false; } QString Area::getHTMLCode() const { return ""; } QString Area::attribute(const QString & name) const { return _attributes[name.lower()]; } void Area::setAttribute(const QString & name, const QString & value) { _attributes.replace(name.lower(),value); if (value.isEmpty()) _attributes.remove(name.lower()); } AttributeIterator Area::firstAttribute() const { return _attributes.begin(); } AttributeIterator Area::lastAttribute() const { return _attributes.end(); } bool Area::setCoords(const QString &) { return true; } void Area::moveSelectionPoint(QRect*, const QPoint &) {} // Default implementation; is specified by subclasses QString Area::coordsToString() const { return ""; } Area::ShapeType Area::type() const { return _type; } void Area::setArea(const Area & copy) { delete _coords; delete _selectionPoints; _coords=new QPointArray(copy.coords()->copy()); _selectionPoints= new SelectionPointList(); currentHighlighted=-1; // Need a deep copy of the list for (QRect *r=copy.selectionPoints()->first();r!=0L;r=copy.selectionPoints()->next()) _selectionPoints->append(new QRect( r->topLeft(),r->bottomRight() ) ); _finished=copy.finished(); _isSelected=copy.isSelected(); _rect = copy.rect(); for (AttributeIterator it = copy.firstAttribute();it!=copy.lastAttribute();++it) { setAttribute(it.key(),it.data()); } setMoving(copy.isMoving()); // _listViewItem=0L; } void Area::setListViewItem(QListViewItem* item) { _listViewItem=item; } void Area::deleteListViewItem() { delete _listViewItem; _listViewItem = 0L; } void Area::setRect(const QRect & r) { _rect=r; updateSelectionPoints(); } QRect Area::rect() const { return _rect; } void Area::setMoving(bool b) { _isMoving=b; } void Area::moveBy(int dx, int dy) { _rect.moveBy(dx,dy); for (uint i=0;i<_coords->size();i++) { int newX=_coords->point(i).x()+dx; int newY=_coords->point(i).y()+dy; _coords->setPoint(i,newX,newY); } for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { r->moveBy(dx,dy); } } void Area::moveTo(int x, int y) { int dx=x-rect().left(); int dy=y-rect().top(); moveBy(dx,dy); } uint Area::countSelectionPoints() const { return (uint) selectionPoints()->count(); } int Area::addCoord(const QPoint & p) { _coords->resize(_coords->size()+1); _coords->setPoint(_coords->size()-1,p); QRect *r= new QRect(0,0,SELSIZE,SELSIZE); r->moveCenter(p); _selectionPoints->append(r); setRect(_coords->boundingRect()); return _coords->size()-1; } void Area::insertCoord(int pos, const QPoint & p) { /* kdDebug() << p.x() << "," << p.y() << endl; if ( _coords->size()>0 ) { for (int i=0; i<_coords->size(); i++) { if (p==_coords->point(i)) { kdDebug() << "same Point already exists" << endl; return; } } } */ _coords->resize(_coords->size()+1); for (int i=_coords->size()-1;i>pos;i--) { _coords->setPoint(i,_coords->point(i-1)); } _coords->setPoint(pos, p); QRect *r= new QRect(0,0,SELSIZE,SELSIZE); r->moveCenter(p); _selectionPoints->insert(pos,r); setRect(_coords->boundingRect()); } void Area::removeCoord(int pos) { int count=_coords->size(); if (count<4) { kdDebug() << "Danger : trying to remove coordinate from Area with less then 4 coordinates !" << endl; return; } for (int i=pos;i<(count-1);i++) _coords->setPoint(i, _coords->point(i+1)); _coords->resize(count-1); _selectionPoints->remove(pos); setRect(_coords->boundingRect()); } bool Area::removeSelectionPoint(QRect * r) { if (_selectionPoints->contains(r)) { removeCoord(_selectionPoints->find(r)); return true; } return false; } void Area::moveCoord(int pos, const QPoint & p) { _coords->setPoint(pos,p); _selectionPoints->at(pos)->moveCenter(p); setRect(_coords->boundingRect()); } void Area::setSelected(bool b) { _isSelected=b; if (_listViewItem) { _listViewItem->setSelected(b); } } void Area::highlightSelectionPoint(int number){ currentHighlighted=number; } QRect Area::selectionRect() const { QRect r = rect(); r.moveBy(-SELSIZE*2,-SELSIZE*2); r.setSize(r.size()+QSize(SELSIZE*4,SELSIZE*4)); return r; } void Area::drawHighlighting(QPainter & p) { if (Area::highlightArea && !isMoving() && _highlightedPixmap) { p.setRasterOp(Qt::CopyROP); QPoint point = QPoint(rect().x(),rect().y()); if (point.x()<0) point.setX(0); if (point.y()<0) point.setY(0); p.drawPixmap( point, *_highlightedPixmap); } } void Area::drawAlt(QPainter & p) { double x,y; double scalex = p.worldMatrix().m11(); // double scaley = p.worldMatrix().m12(); QWMatrix oldMatrix = p.worldMatrix(); p.setWorldMatrix(QWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() )); x = (rect().x()+rect().width()/2)*scalex; y = (rect().y()+rect().height()/2)*scalex; QFontMetrics metrics = p.fontMetrics(); int w = metrics.width(attribute("alt")); x -= w/2; y += metrics.height()/4; if (highlightArea) { p.setRasterOp(Qt::CopyROP); p.setPen(Qt::black); } else { p.setRasterOp(Qt::XorROP); p.setPen(QPen(QColor("white"),1)); } p.drawText(myround(x),myround(y),attribute("alt")); p.setWorldMatrix(oldMatrix); } void Area::draw(QPainter & p) { // Only draw the selection points at base class // the rest is done in the derived classes if (_isSelected) { int i=0; double scalex = p.worldMatrix().m11(); // double scaley = p.worldMatrix().m12(); QWMatrix oldMatrix = p.worldMatrix(); p.setWorldMatrix(QWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() )); for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { // Draw a green circle around the selected point ( only when editing a polygon ) if (i==currentHighlighted) { QRect r2(0,0,15,15); r2.moveCenter(r->center()*scalex); p.setRasterOp(Qt::CopyROP); p.setPen(QPen(QColor("lightgreen"),2)); p.drawEllipse(r2); p.setRasterOp(Qt::XorROP); p.setPen(QPen(QColor("white"),1)); } // Draw the selection point p.setRasterOp(Qt::XorROP); QRect r3(*r); int d = 1; if (scalex > 2) d=0; r3.moveCenter( QPoint((int)(r3.center().x()*scalex),(int)(r3.center().y()*scalex)) ); p.fillRect(r3,QBrush("white")); /* QRect r3(*r); r3.moveTopLeft( QPoint(r3.left()*scalex+2*(scalex-1), r3.top()*scalex+2*(scalex-1)) ); r3.setSize(r3.size()+QSize(2,2)); //+ r3.moveBy(-1,-1); p.setRasterOp(Qt::CopyROP); p.setPen(QPen(QColor("lightgreen"),1)); p.setBrush(QColor("lightgreen")); p.drawPie(r3,0,5760); p.setPen(QPen(QColor("black"),1)); r3.setSize(r3.size()+QSize(2,2)); r3.moveBy(-1,-1); p.drawEllipse(r3); */ i++; } p.setWorldMatrix(oldMatrix); } if (showAlt) { drawAlt(p); } p.setRasterOp(Qt::XorROP); } QRect* Area::onSelectionPoint(const QPoint & p, double zoom) const { for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { QRect r2(r->topLeft(),r->bottomRight()); r2.moveCenter(r2.center()*zoom); if (r2.contains(p)) { return r; } } return 0L; } /** * returns only the part of the image which is * covered by the area */ QPixmap Area::cutOut(const QImage & image) { if ( 0>=rect().width() || 0>=rect().height() || !rect().intersects(image.rect()) ) { QPixmap dummyPix(10,10); dummyPix.fill(); delete _highlightedPixmap; _highlightedPixmap = 0L; return dummyPix; } // Get the mask from the subclasses QBitmap mask=getMask(); // The rectangle which is part of the image QRect partOfImage=rect(); QRect partOfMask(0,0,mask.width(),mask.height()); // If the area is outside of the image make the // preview smaller if ( (rect().x()+rect().width()) > image.width() ) { partOfImage.setWidth( image.width()-rect().x() ); partOfMask.setWidth( image.width()-rect().x() ); } if ( (rect().x() < 0) ) { partOfImage.setX(0); partOfMask.setX(myabs(rect().x())); } if ( (rect().y()+rect().height()) > image.height() ) { partOfImage.setHeight( image.height()-rect().y() ); partOfMask.setHeight ( image.height()-rect().y() ); } if ( (rect().y() < 0) ) { partOfImage.setY(0); partOfMask.setY(myabs(rect().y())); } QImage tempImage=mask.convertToImage().copy(partOfMask); mask.convertFromImage(tempImage); // partOfImage = partOfImage.normalize(); QImage cut=image.copy(partOfImage); QPixmap pix; // partOfMask = partOfMask.normalize(); if (!partOfMask.isValid()) kdDebug() << "PartofMask not valid : " << partOfMask.x() << "," << partOfMask.y() << "," << partOfMask.width() << "," << partOfMask.height() << "," << endl; /* QBitmap mask2(partOfMask.width(), partOfMask.height()); QPainter p4(&mask2); p4.drawPixmap( QPoint(0,0) ,mask,partOfMask); p4.flush(); p4.end(); */ pix.convertFromImage(cut); setHighlightedPixmap(cut, mask); QPixmap retPix(pix.width(),pix.height()); QPainter p3(&retPix); // if transparent image fill the background // with gimp-like rectangles if (pix.mask()) { QPixmap backPix(32,32); // Gimp like transparent rectangle QPainter p2(&backPix); p2.fillRect(0,0,32,32,QColor(156,149,156)); p2.fillRect(0,16,16,16,QColor(98,105,98)); p2.fillRect(16,0,16,16,QColor(98,105,98)); p2.flush(); p3.setPen(QPen()); p3.fillRect(0,0,pix.width(),pix.height(),QBrush(QColor("black"),backPix)); } p3.drawPixmap(QPoint(0,0),pix); p3.flush(); p3.end(); retPix.setMask(mask); return retPix; } QBitmap Area::getMask() const { QBitmap b; return b; } void Area::setHighlightedPixmap( QImage & im, QBitmap & mask ) { if (!Area::highlightArea) return; delete _highlightedPixmap; QImage image = im.convertDepth( 32 ); QSize size = image.size(); QColor pixel; double r,g,b; // highlight every pixel for (int y=0; y < size.height(); y++) { for (int x=0; x < size.width(); x++) { r = qRed(image.pixel(x,y)); g = qGreen(image.pixel(x,y)); b = qBlue(image.pixel(x,y)); r = (r *123 / 255)+132; g = (g *123 / 255)+132; b = (b *123 / 255)+132; pixel.setRgb( (int) r, (int) g, (int) b); image.setPixel(x,y, pixel.rgb()); } } _highlightedPixmap = new QPixmap(); _highlightedPixmap->convertFromImage( image ); _highlightedPixmap->setMask( mask ); if (_highlightedPixmap->isNull()) kdDebug() << "HighlightedPixmap is null" << endl; } /******************************************************************** * RECTANGLE *******************************************************************/ RectArea::RectArea() : Area() { QRect *p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); _type=Area::Rectangle; } RectArea::~RectArea() { } Area* RectArea::clone() const { Area* areaClone = new RectArea(); areaClone->setArea( *this ); return areaClone; } void RectArea::draw(QPainter & p) { drawHighlighting(p); // p.setRasterOp(Qt::CopyROP); // p.setRasterOp(Qt:: OrROP); // QBrush b(QBrush::SolidPattern); // QBrush b(QBrush::Dense4Pattern); // QBrush b(QBrush::BDiagPattern); // b.setColor(QColor(32,32,32)); // p.fillRect(rect(), b); p.setRasterOp(Qt::XorROP); p.setPen(QPen(QColor("white"),1)); QRect r(rect()); r.setWidth(r.width()+1); r.setHeight(r.height()+1); p.drawRect(r); Area::draw(p); } QBitmap RectArea::getMask() const { QBitmap mask(rect().width(),rect().height()); mask.fill(Qt::color0); QPainter p(&mask); p.setBackgroundColor(Qt::color0); p.setPen(Qt::color1); p.setBrush(Qt::color1); mask.fill(Qt::color1); p.end(); return mask; } QString RectArea::coordsToString() const { QString retStr=QString("%1,%2,%3,%4") .arg(rect().left()) .arg(rect().top()) .arg(rect().right()) .arg(rect().bottom()); return retStr; } bool RectArea::contains(const QPoint & p) const{ return rect().contains(p); } void RectArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p) { selectionPoint->moveCenter(p); int i=0; for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { if (r==selectionPoint) break; i++; } QRect r2(_rect); switch (i) { case 0 : _rect.setLeft(p.x()); _rect.setTop(p.y()); break; case 1 : _rect.setRight(p.x()); _rect.setTop(p.y()); break; case 2 : _rect.setLeft(p.x()); _rect.setBottom(p.y()); break; case 3 : _rect.setRight(p.x()); _rect.setBottom(p.y()); break; } if ( ! _rect.isValid()) _rect=r2; updateSelectionPoints(); } void RectArea::updateSelectionPoints() { _selectionPoints->first()->moveCenter(_rect.topLeft()); _selectionPoints->next()->moveCenter(_rect.topRight()+QPoint(1,0)); _selectionPoints->next()->moveCenter(_rect.bottomLeft()+QPoint(0,1)); _selectionPoints->next()->moveCenter(_rect.bottomRight()+QPoint(1,1)); } bool RectArea::setCoords(const QString & s) { _finished=true; QStringList list=QStringList::split(",",s); QRect r; bool ok=true; QStringList::Iterator it = list.begin(); r.setLeft((*it).toInt(&ok,10));it++; r.setTop((*it).toInt(&ok,10));it++; r.setRight((*it).toInt(&ok,10));it++; r.setBottom((*it).toInt(&ok,10)); if (ok) { setRect(r); return true; } else return false; } QString RectArea::getHTMLCode() const { QString retStr; retStr+="append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); p = new QRect(0,0,SELSIZE,SELSIZE); _selectionPoints->append(p); } CircleArea::~CircleArea() { } Area* CircleArea::clone() const { Area* areaClone = new CircleArea(); areaClone->setArea( *this ); return areaClone; } void CircleArea::draw(QPainter & p) { drawHighlighting(p); /* p.setRasterOp(Qt::CopyROP); QBrush bold = p.brush(); QBrush b(QBrush::Dense5Pattern); b.setColor(QColor("green")); p.setBrush(b); QRect r = _rect; r.moveBy(1,1); r.setSize( r.size()-QSize(2,2) ); p.drawChord(r,0,5760); p.setBrush(bold); */ p.setRasterOp(Qt::XorROP); p.setPen(QPen(QColor("white"),1)); QRect r(_rect); r.setWidth(r.width()+1); r.setHeight(r.height()+1); p.drawEllipse(r); Area::draw(p); } QBitmap CircleArea::getMask() const { QBitmap mask(_rect.width(),_rect.height()); mask.fill(Qt::color0); QPainter p(&mask); p.setBackgroundColor(Qt::color0); p.setPen(Qt::color1); p.setBrush(Qt::color1); p.drawPie(QRect(0,0,_rect.width(),_rect.height()),0,5760); p.flush(); p.end(); return mask; } QString CircleArea::coordsToString() const { QString retStr=QString("%1,%2,%3") .arg(_rect.center().x()) .arg(_rect.center().y()) .arg(_rect.width()/2); return retStr; } bool CircleArea::contains(const QPoint & p) const { QRegion r(_rect,QRegion::Ellipse); return r.contains(p); } void CircleArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p) { selectionPoint->moveCenter(p); int i=0; for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { if (r==selectionPoint) break; i++; } // The code below really sucks, but I have no better idea. // it only makes sure that the circle is perfektly round QPoint newPoint; int diff=myabs(p.x()-_rect.center().x()); if (myabs(p.y()-_rect.center().y())>diff) diff=myabs(p.y()-_rect.center().y()); newPoint.setX( p.x()-_rect.center().x()<0 ? _rect.center().x()-diff : _rect.center().x()+diff); newPoint.setY( p.y()-_rect.center().y()<0 ? _rect.center().y()-diff : _rect.center().y()+diff); switch (i) { case 0 : if (newPoint.x() < _rect.center().x() && newPoint.y() < _rect.center().y()) { _rect.setLeft(newPoint.x()); _rect.setTop(newPoint.y()); } break; case 1 : if (newPoint.x() > _rect.center().x() && newPoint.y() < _rect.center().y()) { _rect.setRight(newPoint.x()); _rect.setTop(newPoint.y()); } break; case 2 : if (newPoint.x() < _rect.center().x() && newPoint.y() > _rect.center().y()) { _rect.setLeft(newPoint.x()); _rect.setBottom(newPoint.y()); } break; case 3 : if (newPoint.x() > _rect.center().x() && newPoint.y() > _rect.center().y()) { _rect.setRight(newPoint.x()); _rect.setBottom(newPoint.y()); } break; } updateSelectionPoints(); } void CircleArea::setRect(const QRect & r) { QRect r2 = r; if ( r2.height() != r2.width() ) r2.setHeight( r2.width() ); Area::setRect(r2); } void CircleArea::updateSelectionPoints() { _selectionPoints->first()->moveCenter(_rect.topLeft()); _selectionPoints->next()->moveCenter(_rect.topRight()); _selectionPoints->next()->moveCenter(_rect.bottomLeft()); _selectionPoints->next()->moveCenter(_rect.bottomRight()); } bool CircleArea::setCoords(const QString & s) { _finished=true; QStringList list=QStringList::split(",",s); bool ok=true; QStringList::Iterator it = list.begin(); int x=(*it).toInt(&ok,10);it++; int y=(*it).toInt(&ok,10);it++; int rad=(*it).toInt(&ok,10); if (!ok) return false; QRect r; r.setWidth(rad*2); r.setHeight(rad*2); r.moveCenter(QPoint(x,y)); setRect(r); return true; } QString CircleArea::getHTMLCode() const { QString retStr; retStr+="setArea( *this ); return areaClone; } void PolyArea::draw(QPainter & p) { drawHighlighting(p); p.setRasterOp(Qt::XorROP); p.setPen(QPen(QColor("white"),1)); if (_coords->count()==0) return; if (_finished) p.drawPolygon ( *_coords,false,0,_coords->count()); else p.drawPolyline ( *_coords,0,_coords->count()); /* p.moveTo(_coords->point(0)); for (int i=1;i<_coords->count();i++) p.lineTo(_coords->point(i)); if (_finished) p.lineTo(_coords->point(0)); */ Area::draw(p); } QBitmap PolyArea::getMask() const { QBitmap mask(_rect.width(),_rect.height()); mask.fill(Qt::color0); QPainter p(&mask); p.setBackgroundColor(Qt::color0); p.setPen(Qt::color1); p.setBrush(Qt::color1); p.setClipping(true); QRegion r(*_coords); r.translate(-_rect.left(),-_rect.top()); p.setClipRegion(r); p.fillRect(QRect(0,0,_rect.width(),_rect.height()),Qt::color1); p.flush(); p.end(); return mask; } QString PolyArea::coordsToString() const { QString retStr; for (uint i=0;i<_coords->count();i++) { retStr.append(QString("%1,%2,") .arg(_coords->point(i).x()) .arg(_coords->point(i).y())); } retStr.remove(retStr.length()-1,1); return retStr; } int PolyArea::distance(const QPoint &p1, const QPoint &p2) { QPoint temp = p1-p2; return temp.manhattanLength(); } bool PolyArea::isBetween(const QPoint &p, const QPoint &p1, const QPoint &p2) { int dist = distance(p,p1)+distance(p,p2)-distance(p1,p2); if (myabs(dist)<1) return true; else return false; } void PolyArea::simplifyCoords() { if (_coords->size()<4) return; QPoint p = _coords->point(0) - _coords->point(1); uint i = 1; while( (i<_coords->size()) && (_coords->size() > 3) ) { p = _coords->point(i-1) - _coords->point(i); if (p.manhattanLength() < 3) removeCoord(i); else i++; } p = _coords->point(0) - _coords->point(1); double angle2; double angle1; if (p.y()==0) angle1 = 1000000000; else angle1 = (double) p.x() / (double) p.y(); i=2; while( (i<_coords->size()) && (_coords->size() > 3) ) { p = _coords->point(i-1) - _coords->point(i); if (p.y()==0) angle2 = 1000000000; else angle2 = (double) p.x() / (double) p.y(); if ( angle2==angle1 ) { kdDebug() << "removing " << i-1 << endl; removeCoord(i-1); } else { i++; kdDebug() << "skipping " << i-1 << " cause " << angle1 << "!= " << angle2 << endl; angle1 = angle2; } } } int PolyArea::addCoord(const QPoint & p) { if (_coords->size()<3) { return Area::addCoord(p); } if (_coords->point(_coords->size()-1) == p) { kdDebug() << "equal Point added" << endl; return -1; } int n=_coords->size(); // QPoint temp = p-_coords->point(0); int nearest = 0; int olddist = distance(p,_coords->point(0)); int mindiff = 999999999; // find the two points, which are the nearest one to the new point for (int i=1; i <= n; i++) { int dist = distance(p,_coords->point(i%n)); int dist2 = distance(_coords->point(i-1),_coords->point(i%n)); int diff = myabs(dist+olddist-dist2); if ( diffcount() >2 ) { QRegion r(*_coords); return r.contains(p); } else return false; } void PolyArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p) { selectionPoint->moveCenter(p); int i=0; for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) { if (r==selectionPoint) break; i++; } _coords->setPoint(i,p); _rect=_coords->boundingRect(); } void PolyArea::updateSelectionPoints() { QRect *r; r=_selectionPoints->first(); for (uint i=0;i<_coords->size();i++) { r->moveCenter(_coords->point(i)); r=_selectionPoints->next(); } } bool PolyArea::setCoords(const QString & s) { _finished=true; QStringList list=QStringList::split(",",s); _coords=new QPointArray(); _selectionPoints= new SelectionPointList(); for (QStringList::Iterator it = list.begin(); it !=list.end(); ++it) { bool ok=true; int newXCoord=(*it).toInt(&ok,10); if (!ok) return false; it++; if (it==list.end()) break; int newYCoord=(*it).toInt(&ok,10); if (!ok) return false; insertCoord(_coords->size(), QPoint(newXCoord,newYCoord)); } return true; } QString PolyArea::getHTMLCode() const { QString retStr; retStr+="resize(_coords->size()-1); _selectionPoints->removeLast(); _finished=b; } QRect PolyArea::selectionRect() const { QRect r = _rect; r.moveBy(-10,-10); r.setSize(r.size()+QSize(21,21)); return r; } /******************************************************************** * DEFAULT *******************************************************************/ DefaultArea::DefaultArea() : Area() { _type=Area::Default; } DefaultArea::~DefaultArea() { } Area* DefaultArea::clone() const { Area* areaClone = new DefaultArea(); areaClone->setArea( *this ); return areaClone; } void DefaultArea::draw(QPainter &) {} QString DefaultArea::getHTMLCode() const { QString retStr; retStr+="add( it.current()->clone() ); } // areaClone->setArea( *this ); return areaClone; } void AreaSelection::add(Area *a) { // if a selection of areas was added get the areas of it AreaSelection *selection=0L; if ( (selection = dynamic_cast ( a ) ) ) { AreaList list = selection->getAreaList(); for (Area* area = list.first(); area != 0L; area = list.next() ) { if ( _areas->find( area ) == -1 ) { _areas->append( area ); // Must come before area->setSelected area->setSelected( true ); } } } else { if ( _areas->find( a ) == -1 ) { _areas->append( a ); // Must come before a->setSelected a->setSelected( true ); } } invalidate(); } void AreaSelection::remove(Area *a) { if (_areas->find(a) == -1) return; a->setSelected( false ); _areas->remove( a ); invalidate(); } void AreaSelection::reset() { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) { it.current()->setSelected( false ); } _areas->clear(); invalidate(); } bool AreaSelection::contains(const QPoint & p) const { bool b=false; AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) { if ( it.current()->contains( p ) ) { b=true; break; } } return b; } QRect* AreaSelection::onSelectionPoint(const QPoint & p, double zoom) const { AreaListIterator it=getAreaListIterator(); if (it.count() != 1) return 0L; QRect* retRect=0L; for ( ; it.current() != 0L; ++it ) { if ( (retRect = it.current()->onSelectionPoint( p , zoom) ) ) { break; } } return retRect; } void AreaSelection::moveSelectionPoint(QRect* selectionPoint, const QPoint & p) { // It's only possible to move a SelectionPoint if only one Area is selected if (_areas->count() != 1) return; _areas->getFirst()->moveSelectionPoint(selectionPoint,p); invalidate(); } void AreaSelection::moveBy(int dx, int dy) { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) it.current()->moveBy(dx,dy); Area::moveBy( dx, dy ); invalidate(); } QString AreaSelection::typeString() const { // if there is only one Area selected // show the name of that Area if ( _areas->count()==0 ) return ""; else if ( _areas->count()==1 ) return _areas->getFirst()->typeString(); else return i18n("Number of Areas"); } Area::ShapeType AreaSelection::type() const { // if there is only one Area selected // take the type of that Area if ( _areas->count()==0 ) return Area::None; else if ( _areas->count()==1 ) return _areas->getFirst()->type(); else return Area::Selection; } void AreaSelection::updateSelectionPoints() { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) { it.current()->updateSelectionPoints(); } invalidate(); } QRect AreaSelection::selectionRect() const { if (!_selectionCacheValid) { _selectionCacheValid=true; QRect r; AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) r = r | it.current()->selectionRect(); _cachedSelectionRect=r; } return _cachedSelectionRect; } uint AreaSelection::count() const { return _areas->count(); } bool AreaSelection::isEmpty() const { return _areas->isEmpty(); } AreaList AreaSelection::getAreaList() const { AreaList list(*_areas); return list; } AreaListIterator AreaSelection::getAreaListIterator() const { AreaListIterator it(*_areas); return it; } void AreaSelection::setArea(const Area & copy) { Area *area = copy.clone(); AreaSelection *selection = dynamic_cast(area); if (selection) setAreaSelection(*selection); else { Area::setArea(copy); invalidate(); } } void AreaSelection::setAreaSelection(const AreaSelection & copy) { AreaListIterator it=getAreaListIterator(); AreaListIterator it2=copy.getAreaListIterator(); if (it.count() != it2.count()) return; for ( ; it.current() != 0L; ++it, ++it2 ) it.current()->setArea(*it2.current()); Area::setArea(copy); invalidate(); } void AreaSelection::setAreaList( const AreaList & areas ) { delete _areas; _areas = new AreaList(areas); invalidate(); } void AreaSelection::setRect(const QRect & r) { if ( _areas->count()==1 ) { _areas->getFirst()->setRect(r); } invalidate(); _rect=rect(); updateSelectionPoints(); } QRect AreaSelection::rect() const { if (!_rectCacheValid) { _rectCacheValid=true; QRect r; AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) r = r | it.current()->rect(); _cachedRect=r; } return _cachedRect; } int AreaSelection::addCoord(const QPoint & p) { if ( _areas->count()==1 ) { return _areas->getFirst()->addCoord(p); invalidate(); } return 0; } void AreaSelection::insertCoord(int pos, const QPoint & p) { if ( _areas->count()==1 ) { _areas->getFirst()->insertCoord(pos, p); invalidate(); } } void AreaSelection::removeCoord(int pos) { if ( _areas->count()==1 ) { _areas->getFirst()->removeCoord(pos); invalidate(); } } bool AreaSelection::removeSelectionPoint(QRect * r) { bool result=false; if ( _areas->count()==1 ) { result = _areas->getFirst()->removeSelectionPoint(r); invalidate(); } return result; } SelectionPointList* AreaSelection::selectionPoints() const { if ( _areas->count()==1 ) { return _areas->getFirst()->selectionPoints(); } return _selectionPoints; } void AreaSelection::moveCoord(int pos,const QPoint & p) { if ( _areas->count()==1 ) { _areas->getFirst()->moveCoord(pos,p); invalidate(); } } void AreaSelection::highlightSelectionPoint(int i) { if ( _areas->count()==1 ) { _areas->getFirst()->highlightSelectionPoint(i); invalidate(); } } QPointArray* AreaSelection::coords() const { if ( _areas->count()==1 ) { return _areas->getFirst()->coords(); } return Area::coords(); } QString AreaSelection::attribute(const QString & name) const { if ( _areas->count()==1 ) { return _areas->getFirst()->attribute(name); } return Area::attribute(name); } void AreaSelection::setAttribute(const QString & name, const QString & value) { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) it.current()->setAttribute(name,value); Area::setAttribute(name,value); } AttributeIterator AreaSelection::firstAttribute() const { if ( _areas->count()==1 ) { return _areas->getFirst()->firstAttribute(); } return _attributes.begin(); } AttributeIterator AreaSelection::lastAttribute() const { if ( _areas->count()==1 ) { return _areas->getFirst()->lastAttribute(); } return _attributes.end(); } void AreaSelection::setMoving(bool b) { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) it.current()->setMoving(b); Area::setMoving(b); } bool AreaSelection::isMoving() const { if ( _areas->count()==1 ) { return _areas->getFirst()->isMoving(); } return Area::isMoving(); } /** * Checks if an area is outside the rectangle parameter * returns false if an area has no pixel in common with the rectangle parameter **/ bool AreaSelection::allAreasWithin(const QRect & r) const { if ( ! r.contains(rect()) ) { AreaListIterator it=getAreaListIterator(); for ( ; it.current() != 0L; ++it ) if (!it.current()->rect().intersects(r)) return false; } return true; } void AreaSelection::draw(QPainter &) {}