File indexing completed on 2024-12-01 07:06:42

0001 /***************************************************************************
0002                           drawzone.cpp  -  description
0003                              -------------------
0004     begin                : Wed Apr 4 2001
0005     copyright            : (C) 2001 by Jan Schäfer
0006     email                : j_schaef@informatik.uni-kl.de
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "drawzone.h"
0019 
0020 // Qt
0021 #include <QBitmap>
0022 #include <QDragEnterEvent>
0023 #include <QDropEvent>
0024 #include <QMimeDatabase>
0025 #include <QMimeType>
0026 #include <QMimeData>
0027 #include <QResizeEvent>
0028 #include <QPainter>
0029 #include <QPixmap>
0030 #include <QMouseEvent>
0031 #include <QStandardPaths>
0032 
0033 // KDE Frameworks
0034 #include "kimagemapeditor_debug.h"
0035 
0036 // Local
0037 #include "kimagemapeditor.h"
0038 #include "kimecommands.h"
0039 #include "areacreator.h"
0040 #include "kimearea.h"
0041 
0042 #include "kimecommon.h"
0043 
0044 static QCursor createCircleCursor();
0045 static QCursor createRectangleCursor();
0046 
0047 DrawZone::DrawZone(QWidget *parent,KImageMapEditor* _imageMapEditor)
0048     : QWidget(parent)
0049 {
0050   imageMapEditor=_imageMapEditor;
0051 //  setPicture(QImage());
0052   currentAction=None;
0053   currentArea = nullptr;
0054   oldArea = nullptr;
0055   _zoom=1;
0056   //  QWidget* w = new QWidget(this);
0057   //  setWidget(w);
0058 
0059   if (imageMapEditor->isReadWrite()) {
0060     setMouseTracking(true);
0061     setAcceptDrops(true);
0062   } else {
0063     setMouseTracking(false);
0064   }
0065 
0066   rectangleCursor = createRectangleCursor();
0067   circleCursor = createCircleCursor();
0068 
0069   QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kimagemapeditor/polygoncursor.png" );
0070   polygonCursor = QCursor(QPixmap(path),8,8);
0071 
0072   path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kimagemapeditor/freehandcursor.png" );
0073   freehandCursor = QCursor(QPixmap(path),8,8);
0074 
0075   path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kimagemapeditor/addpointcursor.png" );
0076   addPointCursor = QCursor(QPixmap(path),8,8);
0077 
0078   path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kimagemapeditor/removepointcursor.png" );
0079   removePointCursor = QCursor(QPixmap(path),8,8);
0080 }
0081 
0082 DrawZone::~DrawZone(){
0083 }
0084 
0085 static QCursor createCircleCursor() {
0086   
0087 
0088   // The cross circle cursor
0089   QBitmap b(32,32);
0090   QBitmap b2(32,32);
0091   b2.clear();
0092   b.clear();
0093 
0094   QPainter p;
0095 
0096   p.begin(&b);
0097   // the cross
0098   p.drawLine(0,8,6,8);
0099   p.drawLine(10,8,16,8);
0100   p.drawLine(8,0,8,6);
0101   p.drawLine(8,10,8,16);
0102   // the circle
0103   p.drawEllipse(17,17,8,8);
0104 
0105   p.end();
0106 
0107   p.begin(&b2);
0108   // the cross black lines
0109   p.drawLine(0,8,6,8);
0110   p.drawLine(10,8,16,8);
0111   p.drawLine(8,0,8,6);
0112   p.drawLine(8,10,8,16);
0113 
0114   // the cross white lines
0115   p.drawLine(0,7,6,7);
0116   p.drawLine(10,7,16,7);
0117   p.drawLine(7,0,7,6);
0118   p.drawLine(7,10,7,16);
0119 
0120   // the cross white lines
0121   p.drawLine(0,9,6,9);
0122   p.drawLine(10,9,16,9);
0123   p.drawLine(9,0,9,6);
0124   p.drawLine(9,10,9,16);
0125 
0126   // the circles
0127   p.drawEllipse(17,17,8,8);  // black
0128   p.drawEllipse(16,16,10,10);  // white
0129   p.drawEllipse(18,18,6,6);  // white
0130 
0131   p.end();
0132 
0133   return QCursor(b,b2,8,8);
0134 }
0135 
0136 static QCursor createRectangleCursor() {
0137   // The cross rectangle cursor
0138   QBitmap b(32,32);
0139   QBitmap b2(32,32);
0140   b.clear();
0141   b2.clear();
0142 
0143   QPainter p(&b);
0144   // the cross
0145   p.drawLine(0,8,6,8);
0146   p.drawLine(10,8,16,8);
0147   p.drawLine(8,0,8,6);
0148   p.drawLine(8,10,8,16);
0149   // the rectangle
0150   p.drawRect(17,17,8,6);
0151 
0152   p.end();
0153 
0154   p.begin(&b2);
0155   // the cross black lines
0156   p.drawLine(0,8,6,8);
0157   p.drawLine(10,8,16,8);
0158   p.drawLine(8,0,8,6);
0159   p.drawLine(8,10,8,16);
0160 
0161   // the cross white lines
0162   p.drawLine(0,7,6,7);
0163   p.drawLine(10,7,16,7);
0164   p.drawLine(7,0,7,6);
0165   p.drawLine(7,10,7,16);
0166 
0167   // the cross white lines
0168   p.drawLine(0,9,6,9);
0169   p.drawLine(10,9,16,9);
0170   p.drawLine(9,0,9,6);
0171   p.drawLine(9,10,9,16);
0172 
0173   // the rectangles
0174   p.drawRect(17,17,8,6);    // black
0175   p.drawRect(18,18,6,4);  // white
0176   p.drawRect(16,16,10,8); // white
0177 
0178   p.end();
0179 
0180   return QCursor(b,b2,8,8);
0181 }
0182 
0183 void DrawZone::setPicture(const QImage &_image) {
0184     image=_image;
0185 //- zoomedImage.convertFromImage(image);
0186     setZoom(_zoom);
0187 }
0188  
0189 void DrawZone::setZoom(double z)
0190 {
0191   _zoom=z;
0192   zoomedImage = zoomedImage.fromImage(image);
0193   imageRect.setHeight(myround(image.height()*_zoom));
0194   imageRect.setWidth(myround(image.width()*_zoom));
0195   zoomedImage = zoomedImage.scaled(imageRect.size());
0196   /*
0197   zoomedImage = QPixmap(imageRect.width(),imageRect.height());
0198   QPainter p(&zoomedImage);
0199   p.scale(z,z);
0200   QPixmap pix;
0201   pix.fromImage(image);
0202   // if the picture has transparent areas,
0203   // fill them with Gimp like background
0204   if (!pix.mask().isNull()) {
0205     QPixmap backPix(32,32);
0206     QPainter p2(&backPix);
0207     p2.fillRect(0,0,32,32,QColor(156,149,156));
0208     p2.fillRect(0,16,16,16,QColor(98,105,98));
0209     p2.fillRect(16,0,16,16,QColor(98,105,98));
0210     p.setPen(QPen());
0211     p.fillRect(imageRect.left(),imageRect.top(),imageRect.width(),imageRect.height(),QBrush(QColor("black"),backPix));
0212   }
0213   p.drawPixmap(imageRect.left(),imageRect.top(),pix);
0214   */
0215   /*
0216     resizeContents(visibleWidth()>imageRect.width() ? visibleWidth() : imageRect.width(),
0217     visibleHeight()>imageRect.height() ? visibleHeight() : imageRect.height());
0218   */
0219 
0220   
0221   resize(zoomedImage.size());
0222   repaint();//0,0,width(),height());
0223 }
0224 
0225 QPoint DrawZone::translateFromZoom(const QPoint & p) const {
0226     return QPoint((int)(p.x()/_zoom),(int)(p.y()/_zoom));
0227 }
0228 
0229 QRect DrawZone::translateFromZoom(const QRect & p) const {
0230     return QRect((int)(p.x()/_zoom),(int) (p.y()/_zoom),
0231                              (int)(p.width()/_zoom),(int)(p.height()/_zoom));
0232 }
0233 
0234 QPoint DrawZone::translateToZoom(const QPoint & p) const {
0235     return QPoint(myround(p.x()*_zoom),myround(p.y()*_zoom));
0236 }
0237 
0238 QRect DrawZone::translateToZoom(const QRect & r) const {
0239 //  return QRect(round(r.x()*_zoom),round(r.y()*_zoom),
0240 //                           round(r.width()*_zoom),round(r.height()*_zoom));
0241     return QRect((int)(r.x()*_zoom),(int)(r.y()*_zoom),
0242                              (int)(r.width()*_zoom+2),(int)(r.height()*_zoom+2));
0243 }
0244 
0245 void DrawZone::mouseDoubleClickEvent(QMouseEvent* e) {
0246   if ( ! imageMapEditor->isReadWrite())
0247      return;
0248 
0249   QPoint point=e->pos();
0250   point-=imageRect.topLeft();
0251   point=translateFromZoom(point);
0252   Area* a;
0253   if ( currentAction==None &&
0254        (a=imageMapEditor->onArea(point)))
0255   {
0256     imageMapEditor->deselectAll();
0257     imageMapEditor->select(currentArea);
0258     currentArea=imageMapEditor->selected();
0259     imageMapEditor->showTagEditor(imageMapEditor->selected());
0260   }
0261 
0262 }
0263 
0264 QPoint DrawZone::moveIntoImage(QPoint p) {
0265   // Check if it's on picture if not
0266   // move it to the picture's border
0267   if (!imageRect.contains(p)) {
0268     if (p.x()>imageRect.right())
0269       p.setX(imageRect.right());
0270     if (p.x()<imageRect.left())
0271       p.setX(imageRect.left());
0272     if (p.y()>imageRect.bottom())
0273       p.setY(imageRect.bottom());
0274     if (p.y()<imageRect.top())
0275       p.setY(imageRect.top());
0276   }
0277   return p;
0278 }
0279 
0280 
0281 void DrawZone::mousePressRightNone(QMouseEvent* e, QPoint drawStart) {
0282   if ( (currentArea=imageMapEditor->onArea(drawStart)) ) {
0283     if ( ! currentArea->isSelected()) {
0284       imageMapEditor->deselectAll();
0285       imageMapEditor->select(currentArea);
0286     }
0287     currentArea=imageMapEditor->selected();
0288   }
0289   imageMapEditor->slotShowMainPopupMenu(e->globalPos());
0290 }
0291 
0292 void DrawZone::mousePressLeftNoneOnArea(QMouseEvent* e, Area* area) {
0293 
0294   if ( imageMapEditor->currentToolType() == KImageMapEditor::AddPoint )
0295   {
0296     oldArea=area->clone();
0297     currentAction=AddPoint;
0298     setCursor(addPointCursor);
0299   } else {
0300     currentAction=MoveArea;
0301     setCursor(Qt::SizeAllCursor);
0302     
0303     if ( area->isSelected() ) {
0304       if ( (e->modifiers() & Qt::ControlModifier) )
0305     imageMapEditor->deselect(area);
0306     } else {
0307       if ( (e->modifiers() & Qt::ControlModifier) )
0308     imageMapEditor->select( area );
0309       else {
0310     imageMapEditor->deselectAll();
0311     imageMapEditor->select( area );
0312       }
0313     }
0314     
0315     currentArea = imageMapEditor->selected();
0316     currentArea->setMoving(true);
0317 
0318     oldArea=currentArea->clone();
0319   }
0320 }
0321 
0322 
0323 void DrawZone::mousePressLeftNoneOnBackground(QMouseEvent*, QPoint drawStart) {   
0324   KImageMapEditor::ToolType toolType = imageMapEditor->currentToolType();
0325   
0326   if ( (toolType==KImageMapEditor::Rectangle) ||
0327        (toolType==KImageMapEditor::Circle) ||
0328        (toolType==KImageMapEditor::Polygon) ||
0329        (toolType==KImageMapEditor::Freehand))
0330   {
0331     currentArea = AreaCreator::create(toolType);
0332 
0333     currentArea->setRect(QRect(drawStart,drawStart));
0334     currentArea->setSelected(false);
0335     imageMapEditor->deselectAll();
0336     
0337     switch (toolType)   {
0338     case KImageMapEditor::Rectangle : 
0339       currentAction = DrawRectangle; 
0340       break;
0341     case KImageMapEditor::Circle : 
0342       currentAction = DrawCircle; 
0343       break;
0344     case KImageMapEditor::Polygon :
0345       currentAction = DrawPolygon;
0346       currentArea->addCoord(drawStart);
0347       currentSelectionPoint = currentArea->selectionPoints().last();
0348       break;
0349     case KImageMapEditor::Freehand :
0350       currentAction = DrawFreehand;
0351       //currentArea->addCoord(drawStart);
0352       currentArea->setFinished(false);
0353       break;
0354     default: 
0355       break;
0356     }
0357   } else {
0358     // leftclicked with the arrow at an areafree position
0359     if (toolType==KImageMapEditor::Selection)
0360     {
0361       currentArea = nullptr;
0362       imageMapEditor->deselectAll();
0363       // Start drawing a selection rectangle
0364       currentAction=DoSelect;
0365       oldSelectionRect = imageRect;
0366     }
0367   }
0368 }
0369 
0370 
0371 void DrawZone::mousePressLeftNone(QMouseEvent* e, QPoint drawStart, QPoint zoomedPoint) {
0372   qCDebug(KIMAGEMAPEDITOR_LOG) << "mousePressLeftNone";
0373   Area* a;
0374   if ((a = imageMapEditor->selected()) &&
0375       (currentSelectionPoint=a->onSelectionPoint(zoomedPoint,_zoom)))
0376   {
0377     currentArea = a;
0378     if ( (imageMapEditor->currentToolType() == KImageMapEditor::RemovePoint) &&
0379      (imageMapEditor->selected()->selectionPoints().count()>3) )
0380     {
0381       currentAction=RemovePoint;
0382     } else {
0383       currentAction=MoveSelectionPoint;
0384       currentArea->setMoving(true);
0385     }
0386   } else { // leftclick not on selectionpoint but on area
0387     if ((a = imageMapEditor->onArea(drawStart))) {
0388       currentArea = a;
0389       mousePressLeftNoneOnArea(e,currentArea);
0390     } else { 
0391       mousePressLeftNoneOnBackground(e, drawStart);
0392     }
0393   }
0394 }
0395 
0396 
0397 void DrawZone::mousePressNone(QMouseEvent* e, QPoint drawStart, QPoint zoomedPoint) {
0398   if (e->button()==Qt::RightButton) {
0399     mousePressRightNone(e,drawStart);
0400   } else {
0401     if (e->button() == Qt::MiddleButton) {
0402       mouseDoubleClickEvent(e);
0403     } else {
0404       mousePressLeftNone(e,drawStart,zoomedPoint);
0405     }
0406       
0407   } 
0408 
0409 }
0410 
0411 void DrawZone::mousePressEvent(QMouseEvent* e)
0412 {
0413   if ( ! imageMapEditor->isReadWrite())
0414     return;
0415 
0416   drawStart = moveIntoImage(e->pos());
0417   drawLast = drawStart;
0418  
0419   // Translate it to picture coordinates
0420   //  drawStart-=imageRect.topLeft();
0421   QPoint zoomedPoint = drawStart;
0422   drawStart=translateFromZoom(drawStart);
0423 
0424   delete oldArea;
0425   oldArea = nullptr;
0426 
0427   if (currentArea) {
0428     oldArea = currentArea->clone();
0429   } 
0430 
0431   if (currentAction == None) {
0432     mousePressNone(e,drawStart,zoomedPoint);
0433   }
0434 
0435   QRect r;
0436   if (oldArea)
0437     r = oldArea->selectionRect();
0438 
0439   if (currentArea) {
0440     r = r | currentArea->selectionRect();
0441     repaint(translateToZoom(r));
0442   }
0443 
0444 
0445 }
0446 
0447 void DrawZone::mouseReleaseEvent(QMouseEvent *e) {
0448   if ( ! imageMapEditor->isReadWrite())
0449      return;
0450 
0451   QPoint drawEnd= moveIntoImage(e->pos());
0452 
0453   // Translate it to picture coordinates
0454   //  drawEnd-=imageRect.topLeft();
0455   QPoint zoomedPoint=drawEnd;
0456   drawEnd=translateFromZoom(drawEnd);
0457 
0458   switch (currentAction) {
0459   case DrawCircle:
0460   case DrawRectangle:
0461     currentAction = None;
0462     imageMapEditor->commandHistory()->push(
0463       new CreateCommand( imageMapEditor, 
0464                  currentArea ));
0465     break;
0466   case DrawPolygon:
0467     // If the number of Polygonpoints is more than 2
0468     // and clicked on the first PolygonPoint or
0469     // the right Button was pressed the Polygon is finished
0470     if ((currentArea->selectionPoints().count()>2)
0471     && (currentArea->selectionPoints().first()->getRect().contains(drawEnd)
0472         || (e->button()==Qt::RightButton)))
0473     {
0474       currentArea->setFinished(true);
0475       currentAction=None;
0476       imageMapEditor->commandHistory()->push(
0477       new CreateCommand( imageMapEditor, currentArea ));
0478     } else {
0479       currentArea->insertCoord(currentArea->countSelectionPoints()-1, drawEnd);
0480       currentSelectionPoint=currentArea->selectionPoints().last();
0481     }
0482     break;
0483   case DrawFreehand:
0484     currentArea->setFinished(true,false);
0485     currentArea->simplifyCoords();
0486     currentAction=None;
0487     imageMapEditor->commandHistory()->push(
0488     new CreateCommand( imageMapEditor, currentArea ));
0489     break;
0490   case MoveArea: {
0491     QPoint p1 = oldArea->rect().topLeft();
0492     QPoint p2 = imageMapEditor->selected()->rect().topLeft();
0493 
0494     if (p1 != p2) {
0495       imageMapEditor->commandHistory()->push(
0496     new MoveCommand( imageMapEditor, 
0497              imageMapEditor->selected(), 
0498              oldArea->rect().topLeft()));
0499       imageMapEditor->slotAreaChanged(currentArea);
0500     } else {
0501       imageMapEditor->updateSelection();
0502     }
0503     
0504     currentAction=None;
0505     break;
0506   }
0507   case MoveSelectionPoint:
0508     imageMapEditor->commandHistory()->push(
0509     new ResizeCommand( imageMapEditor, 
0510                imageMapEditor->selected(), 
0511                oldArea));
0512     imageMapEditor->slotAreaChanged(currentArea);
0513     currentAction=None;
0514     break;
0515   case RemovePoint:
0516     if (currentSelectionPoint ==
0517     currentArea->onSelectionPoint(zoomedPoint,_zoom)) 
0518     {
0519       currentArea->removeSelectionPoint(currentSelectionPoint);
0520       imageMapEditor->commandHistory()->push(
0521     new RemovePointCommand( imageMapEditor, 
0522                 imageMapEditor->selected(), 
0523                 oldArea));
0524       imageMapEditor->slotAreaChanged(currentArea);
0525     }
0526     currentAction=None;
0527     break;
0528   case AddPoint:
0529     if (currentArea == imageMapEditor->onArea(drawEnd)) {
0530       imageMapEditor->commandHistory()->push(
0531          new AddPointCommand( imageMapEditor, 
0532                   imageMapEditor->selected(), 
0533                   drawEnd));
0534       imageMapEditor->slotAreaChanged(currentArea);
0535     }
0536     currentAction=None;
0537     break;
0538   case DoSelect: {
0539     currentAction=None;
0540     QRect r(drawStart.x(),
0541         drawStart.y(),
0542         drawCurrent.x()-drawStart.x(),
0543         drawCurrent.y()-drawStart.y());
0544     r = r.normalized();
0545 
0546     AreaListIterator it = imageMapEditor->areaList();
0547     while (it.hasNext()) {
0548       Area* a = it.next();
0549       if ( a->rect().intersects(r) )    {
0550         if (!a->isSelected() ) {
0551            imageMapEditor->selectWithoutUpdate( a );
0552         }
0553       } else {
0554         if (a->isSelected()) {
0555            imageMapEditor->deselectWithoutUpdate( a );
0556         }
0557       }
0558     }
0559 
0560     imageMapEditor->updateActionAccess();
0561     imageMapEditor->updateSelection();
0562     repaint(imageRect);
0563     break;
0564   }
0565   default:  
0566     currentAction=None;
0567   }
0568 
0569   imageMapEditor->slotChangeStatusCoords(drawEnd.x(),drawEnd.y());
0570   if (currentArea) {
0571     currentArea->setMoving(false);
0572     repaintArea(*currentArea);
0573   }
0574   
0575   delete oldArea;
0576   oldArea = nullptr;
0577   imageMapEditor->slotUpdateSelectionCoords();
0578 }
0579 
0580 QCursor DrawZone::getCursorOfToolType(KImageMapEditor::ToolType toolType) {
0581   switch(toolType) {
0582   case KImageMapEditor::Rectangle:
0583     return rectangleCursor;
0584   case KImageMapEditor::Circle:
0585     return circleCursor;
0586   case KImageMapEditor::Polygon:
0587     return polygonCursor;
0588   case KImageMapEditor::Freehand:
0589     return freehandCursor;
0590   default:
0591     return Qt::ArrowCursor;
0592   }
0593   return Qt::ArrowCursor;
0594 }
0595 
0596 
0597 void DrawZone::updateCursor(QPoint zoomedPoint) {
0598   AreaSelection* selected = imageMapEditor->selected();
0599   KImageMapEditor::ToolType toolType = imageMapEditor->currentToolType();
0600   SelectionPoint* selectionPoint;
0601 
0602 
0603   if ( imageMapEditor->onArea(drawCurrent) ) {
0604     if (toolType==KImageMapEditor::AddPoint) {
0605     setCursor(addPointCursor);
0606     } else {
0607       setCursor(Qt::SizeAllCursor);
0608     }
0609   } else {
0610     setCursor(getCursorOfToolType(toolType));
0611   }
0612 
0613 
0614   if ( selected )
0615   {
0616     selected->resetSelectionPointState();
0617     selectionPoint = selected->onSelectionPoint(zoomedPoint,_zoom );
0618     if (selectionPoint) {
0619       selectionPoint->setState(SelectionPoint::HighLighted);
0620       setCursor(selectionPoint->cursor());
0621       if (selected->type()==Area::Polygon) {
0622     if ((toolType==KImageMapEditor::RemovePoint) &&
0623         (selected->selectionPoints().count()>3) )
0624     {
0625       setCursor(removePointCursor);
0626       selectionPoint->setState(SelectionPoint::AboutToRemove);
0627     }
0628       }
0629     } 
0630   } 
0631 }
0632 
0633 void DrawZone::mouseMoveSelection(QPoint drawCurrent) {
0634     
0635   QRect r(drawStart.x(),
0636       drawStart.y(),
0637       drawCurrent.x()-drawStart.x(),
0638       drawCurrent.y()-drawStart.y());
0639   r = r.normalized();
0640 
0641   /*
0642   QRect r1,r2,r3,r4;
0643   createBorderRectangles(translateToZoom(oldSelectionRect),r1,r2,r3,r4);
0644   repaint(r1);
0645   repaint(r2);
0646   repaint(r3);
0647   repaint(r4);
0648 
0649   createBorderRectangles(translateToZoom(r),r1,r2,r3,r4);
0650   repaint(r1);
0651   repaint(r2);
0652   repaint(r3);
0653   repaint(r4);
0654   */
0655 
0656   QRect r2 = r.adjusted(-2,-2,2,2);
0657   oldSelectionRect.adjust(-2,-2,2,2);
0658 
0659   repaint(translateToZoom(r2) | translateToZoom(oldSelectionRect));
0660 
0661   oldSelectionRect = r;
0662 }
0663 
0664 void DrawZone::mouseMoveDrawCircle(QPoint drawCurrent) {
0665     // We don't want ellipses
0666     int maxDistance=myabs(drawStart.x()-drawCurrent.x()) >
0667       myabs(drawStart.y()-drawCurrent.y()) ?
0668       myabs(drawStart.x()-drawCurrent.x()) :
0669       myabs(drawStart.y()-drawCurrent.y()) ;
0670 
0671     int xDiff=maxDistance;
0672     int yDiff=maxDistance;
0673 
0674     if ( drawStart.x()-drawCurrent.x() > 0)
0675       xDiff=-xDiff;
0676 
0677     if ( drawStart.y()-drawCurrent.y() > 0)
0678       yDiff=-yDiff;
0679 
0680     QPoint endPoint( drawStart.x()+xDiff, drawStart.y()+yDiff);
0681 
0682     currentArea->setRect(QRect(drawStart,endPoint).normalized());
0683 }
0684 
0685 void DrawZone::mouseMoveEvent(QMouseEvent *e)
0686 {
0687   if ( ! imageMapEditor->isReadWrite())
0688     return;
0689 
0690   drawLast = drawCurrent;
0691   drawCurrent=moveIntoImage(e->pos());
0692 
0693   // Translate to image coordinates
0694   //  drawCurrent-=imageRect.topLeft();
0695   QPoint zoomedPoint=drawCurrent;
0696   drawCurrent=translateFromZoom(drawCurrent);
0697 
0698   QRect oldRect;
0699   if (currentArea)
0700     oldRect=currentArea->rect();
0701 
0702   switch(currentAction) {
0703   case None:
0704     updateCursor(zoomedPoint);
0705     break;
0706   case DoSelect:
0707     mouseMoveSelection(drawCurrent);
0708     break;
0709   case DrawRectangle:
0710     currentArea->setRect(QRect(drawStart,drawCurrent).normalized());
0711     break;
0712   case DrawCircle:
0713     mouseMoveDrawCircle(drawCurrent);
0714     break;
0715   case DrawPolygon:
0716     currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
0717     break;
0718   case DrawFreehand:
0719     currentArea->insertCoord(currentArea->countSelectionPoints(), drawCurrent);
0720     break;
0721   case MoveArea: {
0722     QPoint d = drawCurrent - drawLast;
0723     currentArea->moveBy(d.x(),d.y());
0724     currentArea->setMoving(true);
0725     break;
0726   }
0727   case MoveSelectionPoint:
0728     currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
0729     break;
0730   case RemovePoint:
0731   case AddPoint:
0732     break;
0733   }
0734   
0735   if (currentArea && (currentAction != DoSelect)) {
0736     QRect newRect = currentArea->selectionRect();
0737     newRect.adjust(-SELSIZE, -SELSIZE, SELSIZE, SELSIZE);
0738     QRect r = oldRect;
0739     r.adjust(-SELSIZE, -SELSIZE, SELSIZE, SELSIZE);
0740     repaint(translateToZoom(r) | translateToZoom(newRect));
0741     imageMapEditor->slotUpdateSelectionCoords( currentArea->rect() );
0742   }
0743 
0744   imageMapEditor->slotChangeStatusCoords(drawCurrent.x(),drawCurrent.y());
0745   //repaint();
0746 }
0747 
0748 void DrawZone::createBorderRectangles(
0749   const QRect & r,
0750   QRect & rb,
0751   QRect & lb,
0752   QRect & tb,
0753   QRect & bb)
0754 {
0755   int bw;
0756   bw = (int) (2+2*_zoom); // Border width
0757 
0758   rb.setX(r.x()+r.width()-bw);
0759   rb.setY(r.y());
0760   rb.setWidth(bw+1);
0761   rb.setHeight(r.height());
0762 
0763   lb.setX(r.x());
0764   lb.setY(r.y());
0765   lb.setWidth(bw);
0766   lb.setHeight(r.height());
0767 
0768   tb.setX(r.x());
0769   tb.setY(r.y());
0770   tb.setWidth(r.width());
0771   tb.setHeight(bw);
0772 
0773   bb.setX(r.x());
0774   bb.setY(r.y()+r.height()-bw);
0775   bb.setWidth(r.width());
0776   bb.setHeight(bw+1);
0777 }
0778 
0779 void DrawZone::cancelDrawing()
0780 {
0781   if (   (currentAction == DrawPolygon )
0782       || (currentAction == DrawRectangle )
0783       || (currentAction == DrawCircle )
0784      )
0785   {
0786     currentAction = None;
0787     QRect r = translateToZoom(currentArea->selectionRect());
0788     delete currentArea;
0789     currentArea = nullptr;
0790     repaint(r);
0791     imageMapEditor->slotUpdateSelectionCoords();
0792   }
0793 }
0794 
0795 void DrawZone::repaintArea(const Area & a) {
0796     repaint(translateToZoom(a.selectionRect()));
0797 }
0798 
0799 void DrawZone::repaintRect(const QRect & r) {
0800     repaint(translateToZoom(r));
0801 }
0802 
0803 QSize DrawZone::sizeHint () const {
0804   return zoomedImage.size();
0805 }
0806 
0807 QSize DrawZone::minimumSize() const {
0808   return zoomedImage.size();
0809 }
0810 
0811 
0812 
0813 void DrawZone::paintEvent(QPaintEvent*) {
0814   QPainter p(this);
0815   p.drawPixmap(0,0,zoomedImage);//,clipx,clipy,clipw,cliph);
0816   p.setRenderHint(QPainter::Antialiasing);
0817   p.scale(_zoom,_zoom);
0818 
0819   AreaListIterator it=imageMapEditor->areaList();
0820   while (it.hasNext()) {
0821     it.next()->draw(&p);
0822   }
0823 
0824   // Draw the current drawing Area
0825   if (currentAction != MoveArea &&
0826       currentAction != MoveSelectionPoint &&
0827       currentAction != None &&
0828       currentAction != DoSelect)
0829     {
0830       currentArea->draw(&p);
0831     }
0832 
0833   if (currentAction == DoSelect ) {
0834     QColor front = Qt::white;
0835     front.setAlpha(200);
0836     QPen pen = QPen(front,1);
0837     //    pen.setStyle(Qt::DotLine);
0838     p.setPen(pen);
0839     p.setBrush(QBrush(Qt::NoBrush));
0840 
0841     QRect r( drawStart.x(),
0842          drawStart.y(),
0843          drawCurrent.x()-drawStart.x(),
0844          drawCurrent.y()-drawStart.y());
0845     r = r.normalized();
0846     p.drawRect(r);
0847   }
0848 
0849 
0850   p.end();
0851 
0852   //  p->end();
0853 
0854   // Copy the double buffer into the widget
0855   //  p->drawPixmap(clipx,clipy,doubleBuffer);
0856 
0857 
0858 }
0859 
0860 void DrawZone::dragEnterEvent(QDragEnterEvent*e) {
0861   QList<QUrl> uris = e->mimeData()->urls();
0862 
0863   if ( uris.isEmpty() )
0864     return;
0865 
0866   QMimeDatabase db;
0867   QMimeType draggedMIME = db.mimeTypeForUrl(uris.first());
0868   // qCDebug(KIMAGEMAPEDITOR_LOG) << "***** " << draggedMIME.name();
0869   if ((draggedMIME.name() == "text/html")
0870       || (draggedMIME.name().left(6) == "image/"))
0871     e->accept();
0872 }
0873 
0874 void DrawZone::dropEvent( QDropEvent* e) {
0875   QList<QUrl> urlList = e->mimeData()->urls();
0876   // A file from konqueror was dropped
0877     if (!urlList.isEmpty()) {
0878         imageMapEditor->openFile(urlList.first());
0879     }
0880 }