1 | /*************************************************************************** |
2 | drawzone.cpp - description |
3 | ------------------- |
4 | begin : Wed Apr 4 2001 |
5 | copyright : (C) 2001 by Jan Sch�er |
6 | email : j_schaef@informatik.uni-kl.de |
7 | ***************************************************************************/ |
8 | |
9 | /*************************************************************************** |
10 | * * |
11 | * This program is free software; you can redistribute it and/or modify * |
12 | * it under the terms of the GNU General Public License as published by * |
13 | * the Free Software Foundation; either version 2 of the License, or * |
14 | * (at your option) any later version. * |
15 | * * |
16 | ***************************************************************************/ |
17 | |
18 | // QT |
19 | #include <qbitmap.h> |
20 | #include <qpainter.h> |
21 | #include <qpixmap.h> |
22 | //Added by qt3to4: |
23 | #include <QDropEvent> |
24 | #include <QResizeEvent> |
25 | #include <QDragEnterEvent> |
26 | #include <QMouseEvent> |
27 | |
28 | // KDE |
29 | #include <kdebug.h> |
30 | #include <kglobal.h> |
31 | #include <kstandarddirs.h> |
32 | #include <kapplication.h> |
33 | #include <kmimetype.h> |
34 | #include <kundostack.h> |
35 | |
36 | // Local |
37 | #include "drawzone.h" |
38 | #include "kimagemapeditor.h" |
39 | #include "kimecommands.h" |
40 | #include "areacreator.h" |
41 | #include "kimearea.h" |
42 | |
43 | #include "kimecommon.h" |
44 | |
45 | static QCursor createCircleCursor(); |
46 | static QCursor createRectangleCursor(); |
47 | |
48 | DrawZone::DrawZone(QWidget *parent,KImageMapEditor* _imageMapEditor) |
49 | : QWidget(parent) |
50 | { |
51 | imageMapEditor=_imageMapEditor; |
52 | // setPicture(QImage()); |
53 | currentAction=None; |
54 | currentArea=0L; |
55 | oldArea=0L; |
56 | _zoom=1; |
57 | // QWidget* w = new QWidget(this); |
58 | // setWidget(w); |
59 | |
60 | if (imageMapEditor->isReadWrite()) { |
61 | setMouseTracking(true); |
62 | setAcceptDrops(true); |
63 | } else { |
64 | setMouseTracking(false); |
65 | } |
66 | |
67 | rectangleCursor = createRectangleCursor(); |
68 | circleCursor = createCircleCursor(); |
69 | |
70 | QString path = KGlobal::dirs()->findResource( "data" , "kimagemapeditor/polygoncursor.png" ); |
71 | polygonCursor = QCursor(QPixmap(path),8,8); |
72 | |
73 | path = KGlobal::dirs()->findResource( "data" , "kimagemapeditor/freehandcursor.png" ); |
74 | freehandCursor = QCursor(QPixmap(path),8,8); |
75 | |
76 | path = KGlobal::dirs()->findResource( "data" , "kimagemapeditor/addpointcursor.png" ); |
77 | addPointCursor = QCursor(QPixmap(path),8,8); |
78 | |
79 | path = KGlobal::dirs()->findResource( "data" , "kimagemapeditor/removepointcursor.png" ); |
80 | removePointCursor = QCursor(QPixmap(path),8,8); |
81 | } |
82 | |
83 | DrawZone::~DrawZone(){ |
84 | } |
85 | |
86 | static QCursor createCircleCursor() { |
87 | |
88 | |
89 | // The cross circle cursor |
90 | QBitmap b(32,32); |
91 | QBitmap b2(32,32); |
92 | b2.clear(); |
93 | b.clear(); |
94 | |
95 | QPainter p; |
96 | |
97 | p.begin(&b); |
98 | // the cross |
99 | p.drawLine(0,8,6,8); |
100 | p.drawLine(10,8,16,8); |
101 | p.drawLine(8,0,8,6); |
102 | p.drawLine(8,10,8,16); |
103 | // the circle |
104 | p.drawEllipse(17,17,8,8); |
105 | |
106 | p.end(); |
107 | |
108 | p.begin(&b2); |
109 | // the cross black lines |
110 | p.drawLine(0,8,6,8); |
111 | p.drawLine(10,8,16,8); |
112 | p.drawLine(8,0,8,6); |
113 | p.drawLine(8,10,8,16); |
114 | |
115 | // the cross white lines |
116 | p.drawLine(0,7,6,7); |
117 | p.drawLine(10,7,16,7); |
118 | p.drawLine(7,0,7,6); |
119 | p.drawLine(7,10,7,16); |
120 | |
121 | // the cross white lines |
122 | p.drawLine(0,9,6,9); |
123 | p.drawLine(10,9,16,9); |
124 | p.drawLine(9,0,9,6); |
125 | p.drawLine(9,10,9,16); |
126 | |
127 | // the circles |
128 | p.drawEllipse(17,17,8,8); // black |
129 | p.drawEllipse(16,16,10,10); // white |
130 | p.drawEllipse(18,18,6,6); // white |
131 | |
132 | p.end(); |
133 | |
134 | return QCursor(b,b2,8,8); |
135 | } |
136 | |
137 | static QCursor createRectangleCursor() { |
138 | // The cross rectangle cursor |
139 | QBitmap b(32,32); |
140 | QBitmap b2(32,32); |
141 | b.clear(); |
142 | b2.clear(); |
143 | |
144 | QPainter p(&b); |
145 | // the cross |
146 | p.drawLine(0,8,6,8); |
147 | p.drawLine(10,8,16,8); |
148 | p.drawLine(8,0,8,6); |
149 | p.drawLine(8,10,8,16); |
150 | // the rectangle |
151 | p.drawRect(17,17,8,6); |
152 | |
153 | p.end(); |
154 | |
155 | p.begin(&b2); |
156 | // the cross black lines |
157 | p.drawLine(0,8,6,8); |
158 | p.drawLine(10,8,16,8); |
159 | p.drawLine(8,0,8,6); |
160 | p.drawLine(8,10,8,16); |
161 | |
162 | // the cross white lines |
163 | p.drawLine(0,7,6,7); |
164 | p.drawLine(10,7,16,7); |
165 | p.drawLine(7,0,7,6); |
166 | p.drawLine(7,10,7,16); |
167 | |
168 | // the cross white lines |
169 | p.drawLine(0,9,6,9); |
170 | p.drawLine(10,9,16,9); |
171 | p.drawLine(9,0,9,6); |
172 | p.drawLine(9,10,9,16); |
173 | |
174 | // the rectangles |
175 | p.drawRect(17,17,8,6); // black |
176 | p.drawRect(18,18,6,4); // white |
177 | p.drawRect(16,16,10,8); // white |
178 | |
179 | p.end(); |
180 | |
181 | return QCursor(b,b2,8,8); |
182 | } |
183 | |
184 | void DrawZone::setPicture(const QImage &_image) { |
185 | image=_image; |
186 | //- zoomedImage.convertFromImage(image); |
187 | setZoom(_zoom); |
188 | } |
189 | |
190 | void DrawZone::setZoom(double z) |
191 | { |
192 | _zoom=z; |
193 | zoomedImage = zoomedImage.fromImage(image); |
194 | imageRect.setHeight(myround(image.height()*_zoom)); |
195 | imageRect.setWidth(myround(image.width()*_zoom)); |
196 | zoomedImage = zoomedImage.scaled(imageRect.size()); |
197 | /* |
198 | zoomedImage = QPixmap(imageRect.width(),imageRect.height()); |
199 | QPainter p(&zoomedImage); |
200 | p.scale(z,z); |
201 | QPixmap pix; |
202 | pix.fromImage(image); |
203 | // if the picture has transparent areas, |
204 | // fill them with Gimp like background |
205 | if (!pix.mask().isNull()) { |
206 | QPixmap backPix(32,32); |
207 | QPainter p2(&backPix); |
208 | p2.fillRect(0,0,32,32,QColor(156,149,156)); |
209 | p2.fillRect(0,16,16,16,QColor(98,105,98)); |
210 | p2.fillRect(16,0,16,16,QColor(98,105,98)); |
211 | p.setPen(QPen()); |
212 | p.fillRect(imageRect.left(),imageRect.top(),imageRect.width(),imageRect.height(),QBrush(QColor("black"),backPix)); |
213 | } |
214 | p.drawPixmap(imageRect.left(),imageRect.top(),pix); |
215 | */ |
216 | /* |
217 | resizeContents(visibleWidth()>imageRect.width() ? visibleWidth() : imageRect.width(), |
218 | visibleHeight()>imageRect.height() ? visibleHeight() : imageRect.height()); |
219 | */ |
220 | |
221 | |
222 | resize(zoomedImage.size()); |
223 | repaint();//0,0,width(),height()); |
224 | } |
225 | |
226 | QPoint DrawZone::translateFromZoom(const QPoint & p) const { |
227 | return QPoint((int)(p.x()/_zoom),(int)(p.y()/_zoom)); |
228 | } |
229 | |
230 | QRect DrawZone::translateFromZoom(const QRect & p) const { |
231 | return QRect((int)(p.x()/_zoom),(int) (p.y()/_zoom), |
232 | (int)(p.width()/_zoom),(int)(p.height()/_zoom)); |
233 | } |
234 | |
235 | QPoint DrawZone::translateToZoom(const QPoint & p) const { |
236 | return QPoint(myround(p.x()*_zoom),myround(p.y()*_zoom)); |
237 | } |
238 | |
239 | QRect DrawZone::translateToZoom(const QRect & r) const { |
240 | // return QRect(round(r.x()*_zoom),round(r.y()*_zoom), |
241 | // round(r.width()*_zoom),round(r.height()*_zoom)); |
242 | return QRect((int)(r.x()*_zoom),(int)(r.y()*_zoom), |
243 | (int)(r.width()*_zoom+2),(int)(r.height()*_zoom+2)); |
244 | } |
245 | |
246 | void DrawZone::mouseDoubleClickEvent(QMouseEvent* e) { |
247 | if ( ! imageMapEditor->isReadWrite()) |
248 | return; |
249 | |
250 | QPoint point=e->pos(); |
251 | point-=imageRect.topLeft(); |
252 | point=translateFromZoom(point); |
253 | Area* a; |
254 | if ( currentAction==None && |
255 | (a=imageMapEditor->onArea(point))) |
256 | { |
257 | imageMapEditor->deselectAll(); |
258 | imageMapEditor->select(currentArea); |
259 | currentArea=imageMapEditor->selected(); |
260 | imageMapEditor->showTagEditor(imageMapEditor->selected()); |
261 | } |
262 | |
263 | } |
264 | |
265 | QPoint DrawZone::moveIntoImage(QPoint p) { |
266 | // Check if it's on picture if not |
267 | // move it to the picture's border |
268 | if (!imageRect.contains(p)) { |
269 | if (p.x()>imageRect.right()) |
270 | p.setX(imageRect.right()); |
271 | if (p.x()<imageRect.left()) |
272 | p.setX(imageRect.left()); |
273 | if (p.y()>imageRect.bottom()) |
274 | p.setY(imageRect.bottom()); |
275 | if (p.y()<imageRect.top()) |
276 | p.setY(imageRect.top()); |
277 | } |
278 | return p; |
279 | } |
280 | |
281 | |
282 | void DrawZone::mousePressRightNone(QMouseEvent* e, QPoint drawStart) { |
283 | if ( (currentArea=imageMapEditor->onArea(drawStart)) ) { |
284 | if ( ! currentArea->isSelected()) { |
285 | imageMapEditor->deselectAll(); |
286 | imageMapEditor->select(currentArea); |
287 | } |
288 | currentArea=imageMapEditor->selected(); |
289 | } |
290 | imageMapEditor->slotShowMainPopupMenu(e->globalPos()); |
291 | } |
292 | |
293 | void DrawZone::mousePressLeftNoneOnArea(QMouseEvent* e, Area* area) { |
294 | |
295 | if ( imageMapEditor->currentToolType() == KImageMapEditor::AddPoint ) |
296 | { |
297 | oldArea=area->clone(); |
298 | currentAction=AddPoint; |
299 | setCursor(addPointCursor); |
300 | } else { |
301 | currentAction=MoveArea; |
302 | setCursor(Qt::SizeAllCursor); |
303 | |
304 | if ( area->isSelected() ) { |
305 | if ( (e->modifiers() & Qt::ControlModifier) ) |
306 | imageMapEditor->deselect(area); |
307 | } else { |
308 | if ( (e->modifiers() & Qt::ControlModifier) ) |
309 | imageMapEditor->select( area ); |
310 | else { |
311 | imageMapEditor->deselectAll(); |
312 | imageMapEditor->select( area ); |
313 | } |
314 | } |
315 | |
316 | currentArea = imageMapEditor->selected(); |
317 | currentArea->setMoving(true); |
318 | |
319 | oldArea=currentArea->clone(); |
320 | } |
321 | } |
322 | |
323 | |
324 | void DrawZone::mousePressLeftNoneOnBackground(QMouseEvent*, QPoint drawStart) { |
325 | KImageMapEditor::ToolType toolType = imageMapEditor->currentToolType(); |
326 | |
327 | if ( (toolType==KImageMapEditor::Rectangle) || |
328 | (toolType==KImageMapEditor::Circle) || |
329 | (toolType==KImageMapEditor::Polygon) || |
330 | (toolType==KImageMapEditor::Freehand)) |
331 | { |
332 | currentArea = AreaCreator::create(toolType); |
333 | |
334 | currentArea->setRect(QRect(drawStart,drawStart)); |
335 | currentArea->setSelected(false); |
336 | imageMapEditor->deselectAll(); |
337 | |
338 | switch (toolType) { |
339 | case KImageMapEditor::Rectangle : |
340 | currentAction = DrawRectangle; |
341 | break; |
342 | case KImageMapEditor::Circle : |
343 | currentAction = DrawCircle; |
344 | break; |
345 | case KImageMapEditor::Polygon : |
346 | currentAction = DrawPolygon; |
347 | currentArea->addCoord(drawStart); |
348 | currentSelectionPoint = currentArea->selectionPoints().last(); |
349 | break; |
350 | case KImageMapEditor::Freehand : |
351 | currentAction = DrawFreehand; |
352 | //currentArea->addCoord(drawStart); |
353 | currentArea->setFinished(false); |
354 | break; |
355 | default: |
356 | break; |
357 | } |
358 | } else { |
359 | // leftclicked with the arrow at an areafree position |
360 | if (toolType==KImageMapEditor::Selection) |
361 | { |
362 | currentArea=0L; |
363 | imageMapEditor->deselectAll(); |
364 | // Start drawing a selection rectangle |
365 | currentAction=DoSelect; |
366 | oldSelectionRect = imageRect; |
367 | } |
368 | } |
369 | } |
370 | |
371 | |
372 | void DrawZone::mousePressLeftNone(QMouseEvent* e, QPoint drawStart, QPoint zoomedPoint) { |
373 | kDebug() << "mousePressLeftNone" ; |
374 | Area* a; |
375 | if ((a = imageMapEditor->selected()) && |
376 | (currentSelectionPoint=a->onSelectionPoint(zoomedPoint,_zoom))) |
377 | { |
378 | currentArea = a; |
379 | if ( (imageMapEditor->currentToolType() == KImageMapEditor::RemovePoint) && |
380 | (imageMapEditor->selected()->selectionPoints().count()>3) ) |
381 | { |
382 | currentAction=RemovePoint; |
383 | } else { |
384 | currentAction=MoveSelectionPoint; |
385 | currentArea->setMoving(true); |
386 | } |
387 | } else { // leftclick not on selectionpoint but on area |
388 | if ((a = imageMapEditor->onArea(drawStart))) { |
389 | currentArea = a; |
390 | mousePressLeftNoneOnArea(e,currentArea); |
391 | } else { |
392 | mousePressLeftNoneOnBackground(e, drawStart); |
393 | } |
394 | } |
395 | } |
396 | |
397 | |
398 | void DrawZone::mousePressNone(QMouseEvent* e, QPoint drawStart, QPoint zoomedPoint) { |
399 | if (e->button()==Qt::RightButton) { |
400 | mousePressRightNone(e,drawStart); |
401 | } else { |
402 | if (e->button()==Qt::MidButton) { |
403 | mouseDoubleClickEvent(e); |
404 | } else { |
405 | mousePressLeftNone(e,drawStart,zoomedPoint); |
406 | } |
407 | |
408 | } |
409 | |
410 | } |
411 | |
412 | void DrawZone::mousePressEvent(QMouseEvent* e) |
413 | { |
414 | if ( ! imageMapEditor->isReadWrite()) |
415 | return; |
416 | |
417 | drawStart = moveIntoImage(e->pos()); |
418 | drawLast = drawStart; |
419 | |
420 | // Translate it to picture coordinates |
421 | // drawStart-=imageRect.topLeft(); |
422 | QPoint zoomedPoint = drawStart; |
423 | drawStart=translateFromZoom(drawStart); |
424 | |
425 | delete oldArea; |
426 | oldArea=0L; |
427 | |
428 | if (currentArea) { |
429 | oldArea = currentArea->clone(); |
430 | } |
431 | |
432 | if (currentAction == None) { |
433 | mousePressNone(e,drawStart,zoomedPoint); |
434 | } |
435 | |
436 | QRect r; |
437 | if (oldArea) |
438 | r = oldArea->selectionRect(); |
439 | |
440 | if (currentArea) { |
441 | r = r | currentArea->selectionRect(); |
442 | repaint(translateToZoom(r)); |
443 | } |
444 | |
445 | |
446 | } |
447 | |
448 | void DrawZone::mouseReleaseEvent(QMouseEvent *e) { |
449 | if ( ! imageMapEditor->isReadWrite()) |
450 | return; |
451 | |
452 | QPoint drawEnd= moveIntoImage(e->pos()); |
453 | |
454 | // Translate it to picture coordinates |
455 | // drawEnd-=imageRect.topLeft(); |
456 | QPoint zoomedPoint=drawEnd; |
457 | drawEnd=translateFromZoom(drawEnd); |
458 | |
459 | switch (currentAction) { |
460 | case DrawCircle: |
461 | case DrawRectangle: |
462 | currentAction = None; |
463 | imageMapEditor->commandHistory()->push( |
464 | new CreateCommand( imageMapEditor, |
465 | currentArea )); |
466 | break; |
467 | case DrawPolygon: |
468 | // If the number of Polygonpoints is more than 2 |
469 | // and clicked on the first PolygonPoint or |
470 | // the right Button was pressed the Polygon is finished |
471 | if ((currentArea->selectionPoints().count()>2) |
472 | && (currentArea->selectionPoints().first()->getRect().contains(drawEnd) |
473 | || (e->button()==Qt::RightButton))) |
474 | { |
475 | currentArea->setFinished(true); |
476 | currentAction=None; |
477 | imageMapEditor->commandHistory()->push( |
478 | new CreateCommand( imageMapEditor, currentArea )); |
479 | } else { |
480 | currentArea->insertCoord(currentArea->countSelectionPoints()-1, drawEnd); |
481 | currentSelectionPoint=currentArea->selectionPoints().last(); |
482 | } |
483 | break; |
484 | case DrawFreehand: |
485 | currentArea->setFinished(true,false); |
486 | currentArea->simplifyCoords(); |
487 | currentAction=None; |
488 | imageMapEditor->commandHistory()->push( |
489 | new CreateCommand( imageMapEditor, currentArea )); |
490 | break; |
491 | case MoveArea: { |
492 | QPoint p1 = oldArea->rect().topLeft(); |
493 | QPoint p2 = imageMapEditor->selected()->rect().topLeft(); |
494 | |
495 | if (p1 != p2) { |
496 | imageMapEditor->commandHistory()->push( |
497 | new MoveCommand( imageMapEditor, |
498 | imageMapEditor->selected(), |
499 | oldArea->rect().topLeft())); |
500 | imageMapEditor->slotAreaChanged(currentArea); |
501 | } else { |
502 | imageMapEditor->updateSelection(); |
503 | } |
504 | |
505 | currentAction=None; |
506 | break; |
507 | } |
508 | case MoveSelectionPoint: |
509 | imageMapEditor->commandHistory()->push( |
510 | new ResizeCommand( imageMapEditor, |
511 | imageMapEditor->selected(), |
512 | oldArea)); |
513 | imageMapEditor->slotAreaChanged(currentArea); |
514 | currentAction=None; |
515 | break; |
516 | case RemovePoint: |
517 | if (currentSelectionPoint == |
518 | currentArea->onSelectionPoint(zoomedPoint,_zoom)) |
519 | { |
520 | currentArea->removeSelectionPoint(currentSelectionPoint); |
521 | imageMapEditor->commandHistory()->push( |
522 | new RemovePointCommand( imageMapEditor, |
523 | imageMapEditor->selected(), |
524 | oldArea)); |
525 | imageMapEditor->slotAreaChanged(currentArea); |
526 | } |
527 | currentAction=None; |
528 | break; |
529 | case AddPoint: |
530 | if (currentArea == imageMapEditor->onArea(drawEnd)) { |
531 | imageMapEditor->commandHistory()->push( |
532 | new AddPointCommand( imageMapEditor, |
533 | imageMapEditor->selected(), |
534 | drawEnd)); |
535 | imageMapEditor->slotAreaChanged(currentArea); |
536 | } |
537 | currentAction=None; |
538 | break; |
539 | case DoSelect: { |
540 | currentAction=None; |
541 | QRect r(drawStart.x(), |
542 | drawStart.y(), |
543 | drawCurrent.x()-drawStart.x(), |
544 | drawCurrent.y()-drawStart.y()); |
545 | r = r.normalized(); |
546 | |
547 | AreaListIterator it = imageMapEditor->areaList(); |
548 | while (it.hasNext()) { |
549 | Area* a = it.next(); |
550 | if ( a->rect().intersects(r) ) { |
551 | if (!a->isSelected() ) { |
552 | imageMapEditor->selectWithoutUpdate( a ); |
553 | } |
554 | } else { |
555 | if (a->isSelected()) { |
556 | imageMapEditor->deselectWithoutUpdate( a ); |
557 | } |
558 | } |
559 | } |
560 | |
561 | imageMapEditor->updateActionAccess(); |
562 | imageMapEditor->updateSelection(); |
563 | repaint(imageRect); |
564 | break; |
565 | } |
566 | default: |
567 | currentAction=None; |
568 | } |
569 | |
570 | imageMapEditor->slotChangeStatusCoords(drawEnd.x(),drawEnd.y()); |
571 | if (currentArea) { |
572 | currentArea->setMoving(false); |
573 | repaintArea(*currentArea); |
574 | } |
575 | |
576 | delete oldArea; |
577 | oldArea=0L; |
578 | imageMapEditor->slotUpdateSelectionCoords(); |
579 | } |
580 | |
581 | QCursor DrawZone::getCursorOfToolType(KImageMapEditor::ToolType toolType) { |
582 | switch(toolType) { |
583 | case KImageMapEditor::Rectangle: |
584 | return rectangleCursor; |
585 | case KImageMapEditor::Circle: |
586 | return circleCursor; |
587 | case KImageMapEditor::Polygon: |
588 | return polygonCursor; |
589 | case KImageMapEditor::Freehand: |
590 | return freehandCursor; |
591 | default: |
592 | return Qt::ArrowCursor; |
593 | } |
594 | return Qt::ArrowCursor; |
595 | } |
596 | |
597 | |
598 | void DrawZone::updateCursor(QPoint zoomedPoint) { |
599 | AreaSelection* selected = imageMapEditor->selected(); |
600 | KImageMapEditor::ToolType toolType = imageMapEditor->currentToolType(); |
601 | SelectionPoint* selectionPoint; |
602 | |
603 | |
604 | if ( imageMapEditor->onArea(drawCurrent) ) { |
605 | if (toolType==KImageMapEditor::AddPoint) { |
606 | setCursor(addPointCursor); |
607 | } else { |
608 | setCursor(Qt::SizeAllCursor); |
609 | } |
610 | } else { |
611 | setCursor(getCursorOfToolType(toolType)); |
612 | } |
613 | |
614 | |
615 | if ( selected ) |
616 | { |
617 | selected->resetSelectionPointState(); |
618 | selectionPoint = selected->onSelectionPoint(zoomedPoint,_zoom ); |
619 | if (selectionPoint) { |
620 | selectionPoint->setState(SelectionPoint::HighLighted); |
621 | setCursor(selectionPoint->cursor()); |
622 | if (selected->type()==Area::Polygon) { |
623 | if ((toolType==KImageMapEditor::RemovePoint) && |
624 | (selected->selectionPoints().count()>3) ) |
625 | { |
626 | setCursor(removePointCursor); |
627 | selectionPoint->setState(SelectionPoint::AboutToRemove); |
628 | } |
629 | } |
630 | } |
631 | } |
632 | } |
633 | |
634 | void DrawZone::mouseMoveSelection(QPoint drawCurrent) { |
635 | |
636 | QRect r(drawStart.x(), |
637 | drawStart.y(), |
638 | drawCurrent.x()-drawStart.x(), |
639 | drawCurrent.y()-drawStart.y()); |
640 | r = r.normalized(); |
641 | |
642 | /* |
643 | QRect r1,r2,r3,r4; |
644 | createBorderRectangles(translateToZoom(oldSelectionRect),r1,r2,r3,r4); |
645 | repaint(r1); |
646 | repaint(r2); |
647 | repaint(r3); |
648 | repaint(r4); |
649 | |
650 | createBorderRectangles(translateToZoom(r),r1,r2,r3,r4); |
651 | repaint(r1); |
652 | repaint(r2); |
653 | repaint(r3); |
654 | repaint(r4); |
655 | */ |
656 | |
657 | QRect r2 = r.adjusted(-2,-2,2,2); |
658 | oldSelectionRect.adjust(-2,-2,2,2); |
659 | |
660 | repaint(translateToZoom(r2) | translateToZoom(oldSelectionRect)); |
661 | |
662 | oldSelectionRect = r; |
663 | } |
664 | |
665 | void DrawZone::mouseMoveDrawCircle(QPoint drawCurrent) { |
666 | // We don't want ellipses |
667 | int maxDistance=myabs(drawStart.x()-drawCurrent.x()) > |
668 | myabs(drawStart.y()-drawCurrent.y()) ? |
669 | myabs(drawStart.x()-drawCurrent.x()) : |
670 | myabs(drawStart.y()-drawCurrent.y()) ; |
671 | |
672 | int xDiff=maxDistance; |
673 | int yDiff=maxDistance; |
674 | |
675 | if ( drawStart.x()-drawCurrent.x() > 0) |
676 | xDiff=-xDiff; |
677 | |
678 | if ( drawStart.y()-drawCurrent.y() > 0) |
679 | yDiff=-yDiff; |
680 | |
681 | QPoint endPoint( drawStart.x()+xDiff, drawStart.y()+yDiff); |
682 | |
683 | currentArea->setRect(QRect(drawStart,endPoint).normalized()); |
684 | } |
685 | |
686 | void DrawZone::mouseMoveEvent(QMouseEvent *e) |
687 | { |
688 | if ( ! imageMapEditor->isReadWrite()) |
689 | return; |
690 | |
691 | drawLast = drawCurrent; |
692 | drawCurrent=moveIntoImage(e->pos()); |
693 | |
694 | // Translate to image coordinates |
695 | // drawCurrent-=imageRect.topLeft(); |
696 | QPoint zoomedPoint=drawCurrent; |
697 | drawCurrent=translateFromZoom(drawCurrent); |
698 | |
699 | QRect oldRect; |
700 | if (currentArea) |
701 | oldRect=currentArea->rect(); |
702 | |
703 | switch(currentAction) { |
704 | case None: |
705 | updateCursor(zoomedPoint); |
706 | break; |
707 | case DoSelect: |
708 | mouseMoveSelection(drawCurrent); |
709 | break; |
710 | case DrawRectangle: |
711 | currentArea->setRect(QRect(drawStart,drawCurrent).normalized()); |
712 | break; |
713 | case DrawCircle: |
714 | mouseMoveDrawCircle(drawCurrent); |
715 | break; |
716 | case DrawPolygon: |
717 | currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent); |
718 | break; |
719 | case DrawFreehand: |
720 | currentArea->insertCoord(currentArea->countSelectionPoints(), drawCurrent); |
721 | break; |
722 | case MoveArea: { |
723 | QPoint d = drawCurrent - drawLast; |
724 | currentArea->moveBy(d.x(),d.y()); |
725 | currentArea->setMoving(true); |
726 | break; |
727 | } |
728 | case MoveSelectionPoint: |
729 | currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent); |
730 | break; |
731 | case RemovePoint: |
732 | case AddPoint: |
733 | break; |
734 | } |
735 | |
736 | if (currentArea && (currentAction != DoSelect)) { |
737 | QRect newRect = currentArea->selectionRect(); |
738 | newRect.adjust(-SELSIZE, -SELSIZE, SELSIZE, SELSIZE); |
739 | QRect r = oldRect; |
740 | r.adjust(-SELSIZE, -SELSIZE, SELSIZE, SELSIZE); |
741 | repaint(translateToZoom(r) | translateToZoom(newRect)); |
742 | imageMapEditor->slotUpdateSelectionCoords( currentArea->rect() ); |
743 | } |
744 | |
745 | imageMapEditor->slotChangeStatusCoords(drawCurrent.x(),drawCurrent.y()); |
746 | //repaint(); |
747 | } |
748 | |
749 | void DrawZone::createBorderRectangles( |
750 | const QRect & r, |
751 | QRect & rb, |
752 | QRect & lb, |
753 | QRect & tb, |
754 | QRect & bb) |
755 | { |
756 | int bw; |
757 | bw = (int) (2+2*_zoom); // Border width |
758 | |
759 | rb.setX(r.x()+r.width()-bw); |
760 | rb.setY(r.y()); |
761 | rb.setWidth(bw+1); |
762 | rb.setHeight(r.height()); |
763 | |
764 | lb.setX(r.x()); |
765 | lb.setY(r.y()); |
766 | lb.setWidth(bw); |
767 | lb.setHeight(r.height()); |
768 | |
769 | tb.setX(r.x()); |
770 | tb.setY(r.y()); |
771 | tb.setWidth(r.width()); |
772 | tb.setHeight(bw); |
773 | |
774 | bb.setX(r.x()); |
775 | bb.setY(r.y()+r.height()-bw); |
776 | bb.setWidth(r.width()); |
777 | bb.setHeight(bw+1); |
778 | } |
779 | |
780 | void DrawZone::cancelDrawing() |
781 | { |
782 | if ( (currentAction == DrawPolygon ) |
783 | || (currentAction == DrawRectangle ) |
784 | || (currentAction == DrawCircle ) |
785 | ) |
786 | { |
787 | currentAction = None; |
788 | QRect r = translateToZoom(currentArea->selectionRect()); |
789 | delete currentArea; |
790 | currentArea = 0L; |
791 | repaint(r); |
792 | imageMapEditor->slotUpdateSelectionCoords(); |
793 | } |
794 | } |
795 | |
796 | void DrawZone::repaintArea(const Area & a) { |
797 | repaint(translateToZoom(a.selectionRect())); |
798 | } |
799 | |
800 | void DrawZone::repaintRect(const QRect & r) { |
801 | repaint(translateToZoom(r)); |
802 | } |
803 | |
804 | QSize DrawZone::sizeHint () const { |
805 | return zoomedImage.size(); |
806 | } |
807 | |
808 | QSize DrawZone::minimumSize() const { |
809 | return zoomedImage.size(); |
810 | } |
811 | |
812 | |
813 | |
814 | void DrawZone::paintEvent(QPaintEvent*) { |
815 | QPainter p(this); |
816 | p.drawPixmap(0,0,zoomedImage);//,clipx,clipy,clipw,cliph); |
817 | p.setRenderHint(QPainter::Antialiasing); |
818 | p.scale(_zoom,_zoom); |
819 | |
820 | AreaListIterator it=imageMapEditor->areaList(); |
821 | while (it.hasNext()) { |
822 | it.next()->draw(&p); |
823 | } |
824 | |
825 | // Draw the current drawing Area |
826 | if (currentAction != MoveArea && |
827 | currentAction != MoveSelectionPoint && |
828 | currentAction != None && |
829 | currentAction != DoSelect) |
830 | { |
831 | currentArea->draw(&p); |
832 | } |
833 | |
834 | if (currentAction == DoSelect ) { |
835 | QColor front = Qt::white; |
836 | front.setAlpha(200); |
837 | QPen pen = QPen(front,1); |
838 | // pen.setStyle(Qt::DotLine); |
839 | p.setPen(pen); |
840 | p.setBrush(QBrush(Qt::NoBrush)); |
841 | |
842 | QRect r( drawStart.x(), |
843 | drawStart.y(), |
844 | drawCurrent.x()-drawStart.x(), |
845 | drawCurrent.y()-drawStart.y()); |
846 | r = r.normalized(); |
847 | p.drawRect(r); |
848 | } |
849 | |
850 | |
851 | p.end(); |
852 | |
853 | // p->end(); |
854 | |
855 | // Copy the double buffer into the widget |
856 | // p->drawPixmap(clipx,clipy,doubleBuffer); |
857 | |
858 | |
859 | } |
860 | |
861 | void DrawZone::dragEnterEvent(QDragEnterEvent*e) { |
862 | KUrl::List uris = KUrl::List::fromMimeData( e->mimeData() ); |
863 | |
864 | if ( uris.isEmpty() ) |
865 | return; |
866 | |
867 | KMimeType::Ptr ptr = KMimeType::findByUrl(uris.first()); |
868 | // kDebug() << "***** " << ptr.data()->name(); |
869 | if ((ptr.data()->name() == "text/html" ) |
870 | || (ptr.data()->name().left(6) == "image/" )) |
871 | e->accept(); |
872 | } |
873 | |
874 | void DrawZone::dropEvent( QDropEvent* e) { |
875 | KUrl::List urlList = KUrl::List::fromMimeData( e->mimeData() ); |
876 | // A file from konqueror was dropped |
877 | if (!urlList.isEmpty()) { |
878 | imageMapEditor->openFile(urlList.first()); |
879 | } |
880 | } |
881 | |