You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1750 lines
34 KiB
1750 lines
34 KiB
15 years ago
|
/***************************************************************************
|
||
|
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 <qbitmap.h>
|
||
|
#include <qpointarray.h>
|
||
|
#include <qpainter.h>
|
||
|
#include <qpixmap.h>
|
||
|
#include <qimage.h>
|
||
|
#include <qpen.h>
|
||
|
#include <qbrush.h>
|
||
|
#include <qpalette.h>
|
||
|
#include <qcolor.h>
|
||
|
#include <qlistview.h>
|
||
|
|
||
|
#include <kdebug.h>
|
||
|
|
||
|
#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+="<area ";
|
||
|
retStr+="shape=\"rect\" ";
|
||
|
|
||
|
retStr+=getHTMLAttributes();
|
||
|
|
||
|
retStr+="coords=\""+coordsToString()+"\" ";
|
||
|
retStr+="/>";
|
||
|
return retStr;
|
||
|
|
||
|
}
|
||
|
|
||
|
/********************************************************************
|
||
|
* CIRCLE
|
||
|
*******************************************************************/
|
||
|
|
||
|
|
||
|
CircleArea::CircleArea()
|
||
|
: Area()
|
||
|
{
|
||
|
_type=Area::Circle;
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
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+="<area ";
|
||
|
retStr+="shape=\"circle\" ";
|
||
|
|
||
|
retStr+=getHTMLAttributes();
|
||
|
|
||
|
retStr+="coords=\""+coordsToString()+"\" ";
|
||
|
retStr+="/>";
|
||
|
return retStr;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/********************************************************************
|
||
|
* POLYGON
|
||
|
*******************************************************************/
|
||
|
|
||
|
|
||
|
PolyArea::PolyArea()
|
||
|
: Area()
|
||
|
{
|
||
|
_type=Area::Polygon;
|
||
|
}
|
||
|
|
||
|
PolyArea::~PolyArea() {
|
||
|
}
|
||
|
|
||
|
Area* PolyArea::clone() const
|
||
|
{
|
||
|
Area* areaClone = new PolyArea();
|
||
|
areaClone->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 ( diff<mindiff )
|
||
|
{
|
||
|
mindiff = diff;
|
||
|
nearest = i%n;
|
||
|
}
|
||
|
olddist=dist;
|
||
|
}
|
||
|
|
||
|
insertCoord(nearest, p);
|
||
|
|
||
|
return nearest;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool PolyArea::contains(const QPoint & p) const
|
||
|
{
|
||
|
// A line can't contain a point
|
||
|
if (_coords->count() >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+="<area ";
|
||
|
retStr+="shape=\"poly\" ";
|
||
|
|
||
|
retStr+=getHTMLAttributes();
|
||
|
|
||
|
retStr+="coords=\""+coordsToString()+"\" ";
|
||
|
retStr+="/>";
|
||
|
return retStr;
|
||
|
|
||
|
}
|
||
|
|
||
|
void PolyArea::setFinished(bool b)
|
||
|
{
|
||
|
// The last Point is the same as the first
|
||
|
// so delete it
|
||
|
_coords->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+="<area ";
|
||
|
retStr+="shape=\"default\" ";
|
||
|
|
||
|
retStr+=getHTMLAttributes();
|
||
|
|
||
|
retStr+="/>";
|
||
|
return retStr;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/********************************************************************
|
||
|
* AreaSelection
|
||
|
*******************************************************************/
|
||
|
|
||
|
AreaSelection::AreaSelection()
|
||
|
: Area()
|
||
|
{
|
||
|
_areas = new AreaList();
|
||
|
_name = "Selection";
|
||
|
invalidate();
|
||
|
}
|
||
|
|
||
|
AreaSelection::~AreaSelection() {
|
||
|
delete _areas;
|
||
|
}
|
||
|
|
||
|
Area* AreaSelection::clone() const
|
||
|
{
|
||
|
AreaSelection* areaClone = new AreaSelection();
|
||
|
|
||
|
// we want a deep copy of the Areas
|
||
|
AreaListIterator it=getAreaListIterator();
|
||
|
|
||
|
for ( ; it.current() != 0L; ++it )
|
||
|
{
|
||
|
areaClone->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 <AreaSelection*> ( 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<AreaSelection*>(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 &)
|
||
|
{}
|
||
|
|
||
|
|