|
|
|
/***************************************************************************
|
|
|
|
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 <tqbitmap.h>
|
|
|
|
#include <tqpointarray.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqpen.h>
|
|
|
|
#include <tqbrush.h>
|
|
|
|
#include <tqpalette.h>
|
|
|
|
#include <tqcolor.h>
|
|
|
|
#include <tqlistview.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include "kimearea.h"
|
|
|
|
#include "kimecommon.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define SELSIZE 7
|
|
|
|
|
|
|
|
|
|
|
|
bool Area::highlightArea;
|
|
|
|
bool Area::showAlt;
|
|
|
|
|
|
|
|
|
|
|
|
Area::Area()
|
|
|
|
{
|
|
|
|
_coords=new TQPointArray();
|
|
|
|
_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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPointArray* Area::coords() const {
|
|
|
|
return _coords;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Area::getHTMLAttributes() const
|
|
|
|
{
|
|
|
|
TQString 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 TQPoint &) const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Area::getHTMLCode() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Area::attribute(const TQString & name) const
|
|
|
|
{
|
|
|
|
return _attributes[name.lower()];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::setAttribute(const TQString & name, const TQString & 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 TQString &) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::moveSelectionPoint(TQRect*, const TQPoint &)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
// Default implementation; is specified by subclasses
|
|
|
|
TQString Area::coordsToString() const
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Area::ShapeType Area::type() const {
|
|
|
|
return _type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::setArea(const Area & copy)
|
|
|
|
{
|
|
|
|
delete _coords;
|
|
|
|
delete _selectionPoints;
|
|
|
|
_coords=new TQPointArray(copy.coords()->copy());
|
|
|
|
_selectionPoints= new SelectionPointList();
|
|
|
|
currentHighlighted=-1;
|
|
|
|
|
|
|
|
// Need a deep copy of the list
|
|
|
|
for (TQRect *r=copy.selectionPoints()->first();r!=0L;r=copy.selectionPoints()->next())
|
|
|
|
_selectionPoints->append(new TQRect( 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(TQListViewItem* item) {
|
|
|
|
_listViewItem=item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::deleteListViewItem()
|
|
|
|
{
|
|
|
|
delete _listViewItem;
|
|
|
|
_listViewItem = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Area::setRect(const TQRect & r)
|
|
|
|
{
|
|
|
|
_rect=r;
|
|
|
|
updateSelectionPoints();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect 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 (TQRect *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 TQPoint & p)
|
|
|
|
{
|
|
|
|
_coords->resize(_coords->size()+1);
|
|
|
|
_coords->setPoint(_coords->size()-1,p);
|
|
|
|
|
|
|
|
TQRect *r= new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
r->moveCenter(p);
|
|
|
|
_selectionPoints->append(r);
|
|
|
|
setRect(_coords->boundingRect());
|
|
|
|
|
|
|
|
return _coords->size()-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::insertCoord(int pos, const TQPoint & 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);
|
|
|
|
|
|
|
|
TQRect *r= new TQRect(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(TQRect * r)
|
|
|
|
{
|
|
|
|
if (_selectionPoints->contains(r))
|
|
|
|
{
|
|
|
|
removeCoord(_selectionPoints->find(r));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Area::moveCoord(int pos, const TQPoint & 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect Area::selectionRect() const {
|
|
|
|
TQRect r = rect();
|
|
|
|
r.moveBy(-SELSIZE*2,-SELSIZE*2);
|
|
|
|
r.setSize(r.size()+TQSize(SELSIZE*4,SELSIZE*4));
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::drawHighlighting(TQPainter & p)
|
|
|
|
{
|
|
|
|
if (Area::highlightArea && !isMoving() && _highlightedPixmap)
|
|
|
|
{
|
|
|
|
p.setRasterOp(TQt::CopyROP);
|
|
|
|
|
|
|
|
TQPoint point = TQPoint(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(TQPainter & p)
|
|
|
|
{
|
|
|
|
double x,y;
|
|
|
|
|
|
|
|
double scalex = p.worldMatrix().m11();
|
|
|
|
// double scaley = p.worldMatrix().m12();
|
|
|
|
|
|
|
|
TQWMatrix oldMatrix = p.worldMatrix();
|
|
|
|
|
|
|
|
p.setWorldMatrix(TQWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() ));
|
|
|
|
|
|
|
|
x = (rect().x()+rect().width()/2)*scalex;
|
|
|
|
y = (rect().y()+rect().height()/2)*scalex;
|
|
|
|
|
|
|
|
TQFontMetrics metrics = p.fontMetrics();
|
|
|
|
|
|
|
|
int w = metrics.width(attribute("alt"));
|
|
|
|
x -= w/2;
|
|
|
|
y += metrics.height()/4;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (highlightArea)
|
|
|
|
{
|
|
|
|
p.setRasterOp(TQt::CopyROP);
|
|
|
|
p.setPen(TQt::black);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
p.setPen(TQPen(TQColor("white"),1));
|
|
|
|
}
|
|
|
|
|
|
|
|
p.drawText(myround(x),myround(y),attribute("alt"));
|
|
|
|
|
|
|
|
p.setWorldMatrix(oldMatrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::draw(TQPainter & 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();
|
|
|
|
|
|
|
|
TQWMatrix oldMatrix = p.worldMatrix();
|
|
|
|
|
|
|
|
p.setWorldMatrix(TQWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() ));
|
|
|
|
|
|
|
|
for (TQRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
|
|
|
|
|
|
|
|
// Draw a green circle around the selected point ( only when editing a polygon )
|
|
|
|
if (i==currentHighlighted) {
|
|
|
|
TQRect r2(0,0,15,15);
|
|
|
|
r2.moveCenter(r->center()*scalex);
|
|
|
|
p.setRasterOp(TQt::CopyROP);
|
|
|
|
p.setPen(TQPen(TQColor("lightgreen"),2));
|
|
|
|
p.drawEllipse(r2);
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
p.setPen(TQPen(TQColor("white"),1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw the selection point
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
|
|
|
|
TQRect r3(*r);
|
|
|
|
int d = 1;
|
|
|
|
if (scalex > 2) d=0;
|
|
|
|
|
|
|
|
r3.moveCenter( TQPoint((int)(r3.center().x()*scalex),(int)(r3.center().y()*scalex)) );
|
|
|
|
|
|
|
|
p.fillRect(r3,TQBrush("white"));
|
|
|
|
/*
|
|
|
|
TQRect r3(*r);
|
|
|
|
r3.moveTopLeft( TQPoint(r3.left()*scalex+2*(scalex-1), r3.top()*scalex+2*(scalex-1)) );
|
|
|
|
|
|
|
|
r3.setSize(r3.size()+TQSize(2,2));
|
|
|
|
//+ r3.moveBy(-1,-1);
|
|
|
|
p.setRasterOp(TQt::CopyROP);
|
|
|
|
p.setPen(TQPen(TQColor("lightgreen"),1));
|
|
|
|
p.setBrush(TQColor("lightgreen"));
|
|
|
|
p.drawPie(r3,0,5760);
|
|
|
|
p.setPen(TQPen(TQColor("black"),1));
|
|
|
|
r3.setSize(r3.size()+TQSize(2,2));
|
|
|
|
r3.moveBy(-1,-1);
|
|
|
|
p.drawEllipse(r3);
|
|
|
|
*/
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
p.setWorldMatrix(oldMatrix);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (showAlt)
|
|
|
|
{
|
|
|
|
drawAlt(p);
|
|
|
|
}
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect* Area::onSelectionPoint(const TQPoint & p, double zoom) const
|
|
|
|
{
|
|
|
|
for (TQRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next())
|
|
|
|
{
|
|
|
|
TQRect 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
|
|
|
|
*/
|
|
|
|
TQPixmap Area::cutOut(const TQImage & image)
|
|
|
|
{
|
|
|
|
if ( 0>=rect().width() ||
|
|
|
|
0>=rect().height() ||
|
|
|
|
!rect().intersects(image.rect()) )
|
|
|
|
{
|
|
|
|
TQPixmap dummyPix(10,10);
|
|
|
|
dummyPix.fill();
|
|
|
|
delete _highlightedPixmap;
|
|
|
|
_highlightedPixmap = 0L;
|
|
|
|
return dummyPix;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the mask from the subclasses
|
|
|
|
TQBitmap mask=getMask();
|
|
|
|
|
|
|
|
// The rectangle which is part of the image
|
|
|
|
TQRect partOfImage=rect();
|
|
|
|
TQRect 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()));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQImage tempImage=mask.convertToImage().copy(partOfMask);
|
|
|
|
mask.convertFromImage(tempImage);
|
|
|
|
|
|
|
|
// partOfImage = partOfImage.normalize();
|
|
|
|
TQImage cut=image.copy(partOfImage);
|
|
|
|
|
|
|
|
TQPixmap pix;
|
|
|
|
|
|
|
|
// partOfMask = partOfMask.normalize();
|
|
|
|
if (!partOfMask.isValid())
|
|
|
|
kdDebug() << "PartofMask not valid : " << partOfMask.x() << "," << partOfMask.y() << ","
|
|
|
|
<< partOfMask.width() << "," << partOfMask.height() << "," << endl;
|
|
|
|
|
|
|
|
/*
|
|
|
|
TQBitmap mask2(partOfMask.width(), partOfMask.height());
|
|
|
|
TQPainter p4(&mask2);
|
|
|
|
p4.drawPixmap( TQPoint(0,0) ,mask,partOfMask);
|
|
|
|
p4.flush();
|
|
|
|
p4.end();
|
|
|
|
*/
|
|
|
|
|
|
|
|
pix.convertFromImage(cut);
|
|
|
|
|
|
|
|
setHighlightedPixmap(cut, mask);
|
|
|
|
|
|
|
|
TQPixmap retPix(pix.width(),pix.height());
|
|
|
|
TQPainter p3(&retPix);
|
|
|
|
|
|
|
|
// if transparent image fill the background
|
|
|
|
// with gimp-like rectangles
|
|
|
|
if (pix.mask()) {
|
|
|
|
TQPixmap backPix(32,32);
|
|
|
|
|
|
|
|
// Gimp like transparent rectangle
|
|
|
|
TQPainter p2(&backPix);
|
|
|
|
p2.fillRect(0,0,32,32,TQColor(156,149,156));
|
|
|
|
p2.fillRect(0,16,16,16,TQColor(98,105,98));
|
|
|
|
p2.fillRect(16,0,16,16,TQColor(98,105,98));
|
|
|
|
p2.flush();
|
|
|
|
|
|
|
|
p3.setPen(TQPen());
|
|
|
|
p3.fillRect(0,0,pix.width(),pix.height(),TQBrush(TQColor("black"),backPix));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
p3.drawPixmap(TQPoint(0,0),pix);
|
|
|
|
p3.flush();
|
|
|
|
p3.end();
|
|
|
|
retPix.setMask(mask);
|
|
|
|
|
|
|
|
return retPix;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQBitmap Area::getMask() const
|
|
|
|
{
|
|
|
|
TQBitmap b;
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Area::setHighlightedPixmap( TQImage & im, TQBitmap & mask )
|
|
|
|
{
|
|
|
|
if (!Area::highlightArea)
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete _highlightedPixmap;
|
|
|
|
|
|
|
|
TQImage image = im.convertDepth( 32 );
|
|
|
|
TQSize size = image.size();
|
|
|
|
TQColor 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 = tqRed(image.pixel(x,y));
|
|
|
|
g = tqGreen(image.pixel(x,y));
|
|
|
|
b = tqBlue(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 TQPixmap();
|
|
|
|
_highlightedPixmap->convertFromImage( image );
|
|
|
|
_highlightedPixmap->setMask( mask );
|
|
|
|
|
|
|
|
if (_highlightedPixmap->isNull())
|
|
|
|
kdDebug() << "HighlightedPixmap is null" << endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* RECTANGLE
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
RectArea::RectArea()
|
|
|
|
: Area()
|
|
|
|
{
|
|
|
|
TQRect *p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(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(TQPainter & p)
|
|
|
|
{
|
|
|
|
|
|
|
|
drawHighlighting(p);
|
|
|
|
// p.setRasterOp(TQt::CopyROP);
|
|
|
|
// p.setRasterOp(TQt:: OrROP);
|
|
|
|
// TQBrush b(TQBrush::SolidPattern);
|
|
|
|
// TQBrush b(TQBrush::Dense4Pattern);
|
|
|
|
// TQBrush b(TQBrush::BDiagPattern);
|
|
|
|
// b.setColor(TQColor(32,32,32));
|
|
|
|
// p.fillRect(rect(), b);
|
|
|
|
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
p.setPen(TQPen(TQColor("white"),1));
|
|
|
|
TQRect r(rect());
|
|
|
|
r.setWidth(r.width()+1);
|
|
|
|
r.setHeight(r.height()+1);
|
|
|
|
p.drawRect(r);
|
|
|
|
|
|
|
|
Area::draw(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQBitmap RectArea::getMask() const
|
|
|
|
{
|
|
|
|
TQBitmap mask(rect().width(),rect().height());
|
|
|
|
|
|
|
|
mask.fill(TQt::color0);
|
|
|
|
TQPainter p(&mask);
|
|
|
|
p.setBackgroundColor(TQt::color0);
|
|
|
|
p.setPen(TQt::color1);
|
|
|
|
p.setBrush(TQt::color1);
|
|
|
|
mask.fill(TQt::color1);
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString RectArea::coordsToString() const
|
|
|
|
{
|
|
|
|
TQString retStr=TQString("%1,%2,%3,%4")
|
|
|
|
.arg(rect().left())
|
|
|
|
.arg(rect().top())
|
|
|
|
.arg(rect().right())
|
|
|
|
.arg(rect().bottom());
|
|
|
|
|
|
|
|
return retStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RectArea::contains(const TQPoint & p) const{
|
|
|
|
return rect().contains(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RectArea::moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p)
|
|
|
|
{
|
|
|
|
selectionPoint->moveCenter(p);
|
|
|
|
int i=0;
|
|
|
|
for (TQRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
|
|
|
|
if (r==selectionPoint)
|
|
|
|
break;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
TQRect 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()+TQPoint(1,0));
|
|
|
|
_selectionPoints->next()->moveCenter(_rect.bottomLeft()+TQPoint(0,1));
|
|
|
|
_selectionPoints->next()->moveCenter(_rect.bottomRight()+TQPoint(1,1));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RectArea::setCoords(const TQString & s)
|
|
|
|
{
|
|
|
|
_finished=true;
|
|
|
|
|
|
|
|
TQStringList list=TQStringList::split(",",s);
|
|
|
|
TQRect r;
|
|
|
|
bool ok=true;
|
|
|
|
TQStringList::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString RectArea::getHTMLCode() const {
|
|
|
|
TQString retStr;
|
|
|
|
retStr+="<area ";
|
|
|
|
retStr+="shape=\"rect\" ";
|
|
|
|
|
|
|
|
retStr+=getHTMLAttributes();
|
|
|
|
|
|
|
|
retStr+="coords=\""+coordsToString()+"\" ";
|
|
|
|
retStr+="/>";
|
|
|
|
return retStr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* CIRCLE
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
CircleArea::CircleArea()
|
|
|
|
: Area()
|
|
|
|
{
|
|
|
|
_type=Area::Circle;
|
|
|
|
TQRect *p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(0,0,SELSIZE,SELSIZE);
|
|
|
|
_selectionPoints->append(p);
|
|
|
|
p = new TQRect(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(TQPainter & p)
|
|
|
|
{
|
|
|
|
drawHighlighting(p);
|
|
|
|
|
|
|
|
/*
|
|
|
|
p.setRasterOp(TQt::CopyROP);
|
|
|
|
TQBrush bold = p.brush();
|
|
|
|
TQBrush b(TQBrush::Dense5Pattern);
|
|
|
|
b.setColor(TQColor("green"));
|
|
|
|
p.setBrush(b);
|
|
|
|
TQRect r = _rect;
|
|
|
|
r.moveBy(1,1);
|
|
|
|
r.setSize( r.size()-TQSize(2,2) );
|
|
|
|
p.drawChord(r,0,5760);
|
|
|
|
p.setBrush(bold);
|
|
|
|
*/
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
p.setPen(TQPen(TQColor("white"),1));
|
|
|
|
|
|
|
|
TQRect r(_rect);
|
|
|
|
r.setWidth(r.width()+1);
|
|
|
|
r.setHeight(r.height()+1);
|
|
|
|
p.drawEllipse(r);
|
|
|
|
|
|
|
|
Area::draw(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQBitmap CircleArea::getMask() const
|
|
|
|
{
|
|
|
|
TQBitmap mask(_rect.width(),_rect.height());
|
|
|
|
|
|
|
|
mask.fill(TQt::color0);
|
|
|
|
TQPainter p(&mask);
|
|
|
|
p.setBackgroundColor(TQt::color0);
|
|
|
|
p.setPen(TQt::color1);
|
|
|
|
p.setBrush(TQt::color1);
|
|
|
|
p.drawPie(TQRect(0,0,_rect.width(),_rect.height()),0,5760);
|
|
|
|
p.flush();
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString CircleArea::coordsToString() const
|
|
|
|
{
|
|
|
|
TQString retStr=TQString("%1,%2,%3")
|
|
|
|
.arg(_rect.center().x())
|
|
|
|
.arg(_rect.center().y())
|
|
|
|
.arg(_rect.width()/2);
|
|
|
|
|
|
|
|
return retStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CircleArea::contains(const TQPoint & p) const
|
|
|
|
{
|
|
|
|
TQRegion r(_rect,TQRegion::Ellipse);
|
|
|
|
return r.contains(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CircleArea::moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p)
|
|
|
|
{
|
|
|
|
selectionPoint->moveCenter(p);
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
for (TQRect *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
|
|
|
|
TQPoint 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 TQRect & r)
|
|
|
|
{
|
|
|
|
TQRect 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 TQString & s)
|
|
|
|
{
|
|
|
|
_finished=true;
|
|
|
|
TQStringList list=TQStringList::split(",",s);
|
|
|
|
bool ok=true;
|
|
|
|
TQStringList::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;
|
|
|
|
TQRect r;
|
|
|
|
r.setWidth(rad*2);
|
|
|
|
r.setHeight(rad*2);
|
|
|
|
r.moveCenter(TQPoint(x,y));
|
|
|
|
setRect(r);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString CircleArea::getHTMLCode() const {
|
|
|
|
TQString 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(TQPainter & p)
|
|
|
|
{
|
|
|
|
drawHighlighting(p);
|
|
|
|
|
|
|
|
p.setRasterOp(TQt::XorROP);
|
|
|
|
p.setPen(TQPen(TQColor("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);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQBitmap PolyArea::getMask() const
|
|
|
|
{
|
|
|
|
TQBitmap mask(_rect.width(),_rect.height());
|
|
|
|
|
|
|
|
mask.fill(TQt::color0);
|
|
|
|
TQPainter p(&mask);
|
|
|
|
p.setBackgroundColor(TQt::color0);
|
|
|
|
p.setPen(TQt::color1);
|
|
|
|
p.setBrush(TQt::color1);
|
|
|
|
p.setClipping(true);
|
|
|
|
TQRegion r(*_coords);
|
|
|
|
r.translate(-_rect.left(),-_rect.top());
|
|
|
|
p.setClipRegion(r);
|
|
|
|
p.fillRect(TQRect(0,0,_rect.width(),_rect.height()),TQt::color1);
|
|
|
|
p.flush();
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString PolyArea::coordsToString() const
|
|
|
|
{
|
|
|
|
TQString retStr;
|
|
|
|
|
|
|
|
for (uint i=0;i<_coords->count();i++) {
|
|
|
|
retStr.append(TQString("%1,%2,")
|
|
|
|
.arg(_coords->point(i).x())
|
|
|
|
.arg(_coords->point(i).y()));
|
|
|
|
}
|
|
|
|
|
|
|
|
retStr.remove(retStr.length()-1,1);
|
|
|
|
|
|
|
|
return retStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PolyArea::distance(const TQPoint &p1, const TQPoint &p2)
|
|
|
|
{
|
|
|
|
TQPoint temp = p1-p2;
|
|
|
|
return temp.manhattanLength();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PolyArea::isBetween(const TQPoint &p, const TQPoint &p1, const TQPoint &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;
|
|
|
|
|
|
|
|
TQPoint 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 TQPoint & 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();
|
|
|
|
|
|
|
|
// TQPoint 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 TQPoint & p) const
|
|
|
|
{
|
|
|
|
// A line can't contain a point
|
|
|
|
if (_coords->count() >2 ) {
|
|
|
|
TQRegion r(*_coords);
|
|
|
|
return r.contains(p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PolyArea::moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p)
|
|
|
|
{
|
|
|
|
selectionPoint->moveCenter(p);
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
for (TQRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
|
|
|
|
if (r==selectionPoint)
|
|
|
|
break;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
_coords->setPoint(i,p);
|
|
|
|
_rect=_coords->boundingRect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PolyArea::updateSelectionPoints()
|
|
|
|
{
|
|
|
|
TQRect *r;
|
|
|
|
r=_selectionPoints->first();
|
|
|
|
|
|
|
|
for (uint i=0;i<_coords->size();i++)
|
|
|
|
{
|
|
|
|
r->moveCenter(_coords->point(i));
|
|
|
|
r=_selectionPoints->next();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PolyArea::setCoords(const TQString & s)
|
|
|
|
{
|
|
|
|
_finished=true;
|
|
|
|
TQStringList list=TQStringList::split(",",s);
|
|
|
|
_coords=new TQPointArray();
|
|
|
|
_selectionPoints= new SelectionPointList();
|
|
|
|
|
|
|
|
for (TQStringList::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(), TQPoint(newXCoord,newYCoord));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString PolyArea::getHTMLCode() const {
|
|
|
|
TQString 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect PolyArea::selectionRect() const
|
|
|
|
{
|
|
|
|
TQRect r = _rect;
|
|
|
|
|
|
|
|
r.moveBy(-10,-10);
|
|
|
|
r.setSize(r.size()+TQSize(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(TQPainter &)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
TQString DefaultArea::getHTMLCode() const {
|
|
|
|
TQString 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 TQPoint & p) const
|
|
|
|
{
|
|
|
|
bool b=false;
|
|
|
|
AreaListIterator it=getAreaListIterator();
|
|
|
|
|
|
|
|
for ( ; it.current() != 0L; ++it )
|
|
|
|
{
|
|
|
|
if ( it.current()->contains( p ) )
|
|
|
|
{
|
|
|
|
b=true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect* AreaSelection::onSelectionPoint(const TQPoint & p, double zoom) const
|
|
|
|
{
|
|
|
|
AreaListIterator it=getAreaListIterator();
|
|
|
|
|
|
|
|
if (it.count() != 1)
|
|
|
|
return 0L;
|
|
|
|
|
|
|
|
TQRect* retRect=0L;
|
|
|
|
|
|
|
|
for ( ; it.current() != 0L; ++it )
|
|
|
|
{
|
|
|
|
if ( (retRect = it.current()->onSelectionPoint( p , zoom) ) )
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retRect;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AreaSelection::moveSelectionPoint(TQRect* selectionPoint, const TQPoint & 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString 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();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TQRect AreaSelection::selectionRect() const
|
|
|
|
{
|
|
|
|
if (!_selectionCacheValid)
|
|
|
|
{
|
|
|
|
_selectionCacheValid=true;
|
|
|
|
TQRect 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 TQRect & r)
|
|
|
|
{
|
|
|
|
if ( _areas->count()==1 )
|
|
|
|
{
|
|
|
|
_areas->getFirst()->setRect(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidate();
|
|
|
|
_rect=rect();
|
|
|
|
updateSelectionPoints();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect AreaSelection::rect() const
|
|
|
|
{
|
|
|
|
if (!_rectCacheValid)
|
|
|
|
{
|
|
|
|
_rectCacheValid=true;
|
|
|
|
TQRect r;
|
|
|
|
AreaListIterator it=getAreaListIterator();
|
|
|
|
|
|
|
|
for ( ; it.current() != 0L; ++it )
|
|
|
|
r = r | it.current()->rect();
|
|
|
|
|
|
|
|
_cachedRect=r;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _cachedRect;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int AreaSelection::addCoord(const TQPoint & p)
|
|
|
|
{
|
|
|
|
if ( _areas->count()==1 )
|
|
|
|
{
|
|
|
|
return _areas->getFirst()->addCoord(p);
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AreaSelection::insertCoord(int pos, const TQPoint & 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(TQRect * 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 TQPoint & 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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQPointArray* AreaSelection::coords() const
|
|
|
|
{
|
|
|
|
if ( _areas->count()==1 )
|
|
|
|
{
|
|
|
|
return _areas->getFirst()->coords();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Area::coords();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString AreaSelection::attribute(const TQString & name) const
|
|
|
|
{
|
|
|
|
if ( _areas->count()==1 )
|
|
|
|
{
|
|
|
|
return _areas->getFirst()->attribute(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Area::attribute(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AreaSelection::setAttribute(const TQString & name, const TQString & 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 TQRect & 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(TQPainter &)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|