1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /**************************************************************************
8 *   Copyright (C) 2007 by Franz Schmid                                    *
9 *   franz.schmid@altmuehlnet.de                                           *
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 *   This program is distributed in the hope that it will be useful,       *
17 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19 *   GNU General Public License for more details.                          *
20 *                                                                         *
21 *   You should have received a copy of the GNU General Public License     *
22 *   along with this program; if not, write to the                         *
23 *   Free Software Foundation, Inc.,                                       *
24 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
25 ***************************************************************************/
26 
27 #include "lensdialog.h"
28 
29 #include <cmath>
30 
31 #include <QGraphicsSceneHoverEvent>
32 #include <QGraphicsSceneMouseEvent>
33 #include <QRadialGradient>
34 #include <QStyleOptionGraphicsItem>
35 
36 #include "commonstrings.h"
37 #include "iconmanager.h"
38 #include "pageitem_group.h"
39 #include "sccolorengine.h"
40 #include "scpattern.h"
41 #include "selection.h"
42 
LensItem(QRectF geom,LensDialog * parent)43 LensItem::LensItem(QRectF geom, LensDialog *parent) : QGraphicsRectItem(geom)
44 {
45 	dialog = parent;
46 	strength = -100.0;
47 	scaling = 1.0,
48 	handle = -1;
49 	setPen(QPen(Qt::black));
50 	QRadialGradient radialGrad(QPointF(0.5, 0.5), 1.0);
51 	radialGrad.setColorAt(0.0, QColor(255, 0, 0, 127));
52 	radialGrad.setColorAt(0.1, QColor(255, 0, 0, 127));
53 	radialGrad.setColorAt(1.0, QColor(255, 255, 255, 0));
54 	radialGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
55 	setBrush(radialGrad);
56 	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
57 	acceptHoverEvents();
58 
59 }
60 
paint(QPainter * painter,const QStyleOptionGraphicsItem * item,QWidget * widget)61 void LensItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
62 {
63 	Q_UNUSED(widget);
64 	painter->setPen(QPen(Qt::black, 1.0 / item->levelOfDetail));
65 	QRadialGradient radialGrad(QPointF(0.5, 0.5), 1.0);
66 	radialGrad.setColorAt(0.0, QColor(255, 0, 0, 127));
67 	radialGrad.setColorAt(0.1, QColor(255, 0, 0, 127));
68 	radialGrad.setColorAt(1.0, QColor(255, 255, 255, 0));
69 	radialGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
70 	painter->setBrush(radialGrad);
71 	painter->drawEllipse(rect().toRect());
72 	if (item->state & QStyle::State_Selected)
73 	{
74 		scaling = item->levelOfDetail;
75 		double siz = 6.0 / item->levelOfDetail;
76 		QRectF br = boundingRect();
77 		painter->setBrush(Qt::NoBrush);
78 		painter->setPen(QPen(Qt::red, 1.0 / item->levelOfDetail, Qt::DotLine));
79 		painter->drawRect(br);
80 		painter->setBrush(Qt::red);
81 		painter->setPen(Qt::NoPen);
82 		painter->drawRect(QRectF(br.x() + br.width(), br.y() + br.height(), -siz, -siz));
83 		painter->drawRect(QRectF(br.x() + br.width(), br.y(), -siz, siz));
84 		painter->drawRect(QRectF(br.x(), br.y() + br.height(), siz, -siz));
85 		painter->drawRect(QRectF(br.x(), br.y(), siz, siz));
86 	}
87 }
88 
mousePressEvent(QGraphicsSceneMouseEvent * event)89 void LensItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
90 {
91 	mousePoint = event->screenPos();
92 	QRectF br = boundingRect();
93 	double siz = 6.0 / scaling;
94 	if (QRectF(br.x(), br.y(), siz, siz).contains(event->pos()))
95 		handle = 0;
96 	else if (QRectF(br.x() + br.width(), br.y(), -siz, siz).contains(event->pos()))
97 		handle = 1;
98 	else if (QRectF(br.x() + br.width(), br.y() + br.height(), -siz, -siz).contains(event->pos()))
99 		handle = 2;
100 	else if (QRectF(br.x(), br.y() + br.height(), siz, -siz).contains(event->pos()))
101 		handle = 3;
102 	else
103 		handle = -1;
104 	QGraphicsItem::mousePressEvent(event);
105 }
106 
mouseMoveEvent(QGraphicsSceneMouseEvent * event)107 void LensItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
108 {
109 	QRectF r = rect();
110 	double dx = (mousePoint.x() - event->screenPos().x()) / scaling;
111 	if (handle == 0)
112 	{
113 		QPointF tl = r.topLeft();
114 		tl = tl - QPointF(dx, dx);
115 		r.setTopLeft(tl);
116 		setRect(r.normalized());
117 	}
118 	else if (handle == 1)
119 	{
120 		QPointF tl = r.topRight();
121 		tl = tl - QPointF(dx, -dx);
122 		r.setTopRight(tl);
123 		setRect(r.normalized());
124 	}
125 	else if (handle == 2)
126 	{
127 		QPointF tl = r.bottomRight();
128 		tl = tl - QPointF(dx, dx);
129 		r.setBottomRight(tl);
130 		setRect(r.normalized());
131 	}
132 	else if (handle == 3)
133 	{
134 		QPointF tl = r.bottomLeft();
135 		tl = tl - QPointF(dx, -dx);
136 		r.setBottomLeft(tl);
137 		setRect(r.normalized());
138 	}
139 	else
140 		QGraphicsItem::mouseMoveEvent(event);
141 	mousePoint = event->screenPos();
142 	dialog->lensSelected(this);
143 }
144 
mouseReleaseEvent(QGraphicsSceneMouseEvent * event)145 void LensItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
146 {
147 	handle = -1;
148 	updateEffect();
149 	QGraphicsItem::mouseReleaseEvent(event);
150 }
151 
hoverEnterEvent(QGraphicsSceneHoverEvent * event)152 void LensItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
153 {
154 	QPainterPath p;
155 	p.addEllipse(rect());
156 	if ((p.contains(event->pos())) && (isSelected()))
157 		qApp->changeOverrideCursor(QCursor(Qt::SizeAllCursor));
158 	else
159 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
160 }
161 
hoverMoveEvent(QGraphicsSceneHoverEvent * event)162 void LensItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
163 {
164 	QPainterPath p;
165 	p.addEllipse(rect());
166 	if (isSelected())
167 	{
168 		if (p.contains(event->pos()))
169 			qApp->changeOverrideCursor(QCursor(Qt::SizeAllCursor));
170 		else
171 		{
172 			QRectF br = boundingRect();
173 			double siz = 6.0 / scaling;
174 			if (QRectF(br.x(), br.y(), siz, siz).contains(event->pos()))
175 				qApp->changeOverrideCursor(QCursor(Qt::SizeFDiagCursor));
176 			else if (QRectF(br.x() + br.width(), br.y(), -siz, siz).contains(event->pos()))
177 				qApp->changeOverrideCursor(QCursor(Qt::SizeBDiagCursor));
178 			else if (QRectF(br.x() + br.width(), br.y() + br.height(), -siz, -siz).contains(event->pos()))
179 				qApp->changeOverrideCursor(QCursor(Qt::SizeFDiagCursor));
180 			else if (QRectF(br.x(), br.y() + br.height(), siz, -siz).contains(event->pos()))
181 				qApp->changeOverrideCursor(QCursor(Qt::SizeBDiagCursor));
182 			else
183 				qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
184 		}
185 	}
186 	else
187 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
188 }
189 
hoverLeaveEvent(QGraphicsSceneHoverEvent *)190 void LensItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
191 {
192 	qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
193 }
194 
setStrength(double s)195 void LensItem::setStrength(double s)
196 {
197 	strength = s;
198 }
199 
itemChange(GraphicsItemChange change,const QVariant & value)200 QVariant LensItem::itemChange(GraphicsItemChange change, const QVariant &value)
201 {
202 	switch (change)
203 	{
204 		case ItemSelectedChange:
205 			dialog->lensSelected(this);
206 			break;
207 		case ItemPositionHasChanged:
208 			dialog->setLensPositionValues(mapToScene(rect().center()));
209 			updateEffect();
210 			break;
211 		default:
212 			break;
213 	}
214 	return QGraphicsItem::itemChange(change, value);
215 }
216 
updateEffect()217 void LensItem::updateEffect()
218 {
219 	LensItem *item;
220 	for (int a = 0; a < dialog->origPathItem.count(); a++)
221 	{
222 		QGraphicsPathItem* pItem = dialog->origPathItem[a];
223 		QPainterPath path = dialog->origPath[a];
224 		path = pItem->mapToScene(path);
225 		for (int b = 0; b < dialog->lensList.count(); b++)
226 		{
227 			item = dialog->lensList[b];
228 			path = lensDeform(path, item->mapToScene(item->rect().center()), item->rect().width() / 2.0, item->strength / 100.0);
229 		}
230 		path = pItem->mapFromScene(path);
231 		pItem->setPath(path);
232 	}
233 }
234 
lensDeform(const QPainterPath & source,const QPointF & offset,double m_radius,double s)235 QPainterPath LensItem::lensDeform(const QPainterPath &source, const QPointF &offset, double m_radius, double s)
236 {
237 	QPainterPath path;
238 	path.addPath(source);
239 	for (int i = 0; i < path.elementCount(); ++i)
240 	{
241 		const QPainterPath::Element &e = path.elementAt(i);
242 		double dx = e.x - offset.x();
243 		double dy = e.y - offset.y();
244 		double len = m_radius - sqrt(dx * dx + dy * dy);
245 		if (len > 0)
246 			path.setElementPositionAt(i, e.x - s * dx * len / m_radius, e.y - s * dy * len / m_radius);
247 	}
248 	return path;
249 }
250 
LensDialog(QWidget * parent,ScribusDoc * doc)251 LensDialog::LensDialog(QWidget* parent, ScribusDoc *doc) : QDialog(parent)
252 {
253 	setupUi(this);
254 	buttonRemove->setEnabled(false);
255 	setModal(true);
256 	buttonZoomOut->setIcon(QIcon(IconManager::instance().loadIcon("16/zoom-out.png")));
257 	buttonZoomI->setIcon(QIcon(IconManager::instance().loadIcon("16/zoom-in.png")));
258 	addItemsToScene(doc->m_Selection, doc, nullptr, nullptr);
259 	previewWidget->setRenderHint(QPainter::Antialiasing);
260 	previewWidget->setScene(&scene);
261 	isFirst = true;
262 	addLens();
263 	connect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
264 	connect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
265 	connect(spinRadius, SIGNAL(valueChanged(double)), this, SLOT(setNewLensRadius(double)));
266 	connect(spinStrength, SIGNAL(valueChanged(double)), this, SLOT(setNewLensStrength(double)));
267 	connect(buttonAdd, SIGNAL(clicked()), this, SLOT(addLens()));
268 	connect(buttonRemove, SIGNAL(clicked()), this, SLOT(removeLens()));
269 	connect(buttonMagnify, SIGNAL(toggled(bool)), this, SLOT(changeLens()));
270 	connect(buttonZoomI, SIGNAL(clicked()), this, SLOT(doZoomIn()));
271 	connect(buttonZoomOut, SIGNAL(clicked()), this, SLOT(doZoomOut()));
272 	connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
273 	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
274 	connect(&scene, SIGNAL(selectionChanged()), this, SLOT(selectionHasChanged()));
275 }
276 
addItemsToScene(Selection * itemSelection,ScribusDoc * doc,QGraphicsPathItem * parentItem,PageItem * parent)277 void LensDialog::addItemsToScene(Selection* itemSelection, ScribusDoc *doc, QGraphicsPathItem* parentItem, PageItem* parent)
278 {
279 	PageItem *currItem;
280 	double gx, gy, gh, gw;
281 	itemSelection->setGroupRect();
282 	itemSelection->getGroupRect(&gx, &gy, &gw, &gh);
283 	uint selectedItemCount = itemSelection->count();
284 	for (uint i = 0; i < selectedItemCount; ++i)
285 	{
286 		currItem = itemSelection->itemAt(i);
287 		if (currItem->isGroup())
288 			currItem->asGroupFrame()->adjustXYPosition();
289 		FPointArray path = currItem->PoLine;
290 		QPainterPath pp;
291 		if (currItem->itemType() == PageItem::PolyLine)
292 			pp = path.toQPainterPath(false);
293 		else
294 			pp = path.toQPainterPath(true);
295 		origPath.append(pp);
296 		QGraphicsPathItem* pItem = new QGraphicsPathItem(pp, parentItem);
297 		if (parentItem == nullptr)
298 		{
299 			scene.addItem(pItem);
300 			pItem->setPos(currItem->xPos() - gx, currItem->yPos() - gy);
301 			pItem->setRotation(currItem->rotation());
302 		}
303 		else
304 		{
305 			QTransform mm;
306 			mm.rotate(-parent->rotation());
307 			mm.translate(-parent->xPos(), -parent->yPos());
308 			pItem->setPos(mm.map(QPointF(currItem->xPos(), currItem->yPos())));
309 		}
310 		pItem->setZValue(i);
311 		origPathItem.append(pItem);
312 		origPageItem.append(currItem);
313 		if (((currItem->fillColor() == CommonStrings::None) && (currItem->GrType == 0)) || (currItem->isGroup()))
314 			pItem->setBrush(Qt::NoBrush);
315 		else
316 		{
317 			if (currItem->GrType != 0)
318 			{
319 				if (currItem->GrType != Gradient_Pattern)
320 				{
321 					QGradient pat;
322 					double x1 = currItem->GrStartX;
323 					double y1 = currItem->GrStartY;
324 					double x2 = currItem->GrEndX;
325 					double y2 = currItem->GrEndY;
326 					switch (currItem->GrType)
327 					{
328 						case 1:
329 						case 2:
330 						case 3:
331 						case 4:
332 						case 6:
333 							pat = QLinearGradient(x1, y1,  x2, y2);
334 							break;
335 						case 5:
336 						case 7:
337 							pat = QRadialGradient(x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)), x1, y1);
338 							break;
339 					}
340 					QList<VColorStop*> colorStops = currItem->fill_gradient.colorStops();
341 					QColor qStopColor;
342 					for (int offset = 0 ; offset < colorStops.count() ; offset++)
343 					{
344 						qStopColor = colorStops[ offset ]->color;
345 						int h, s, v, sneu, vneu;
346 						int shad = colorStops[offset]->shade;
347 						qStopColor.getHsv(&h, &s, &v);
348 						sneu = s * shad / 100;
349 						vneu = 255 - ((255 - v) * shad / 100);
350 						qStopColor.setHsv(h, sneu, vneu);
351 						qStopColor.setAlphaF(colorStops[offset]->opacity);
352 						pat.setColorAt(colorStops[ offset ]->rampPoint, qStopColor);
353 					}
354 					pItem->setBrush(pat);
355 				}
356 				else if ((currItem->GrType == Gradient_Pattern) && (!currItem->pattern().isEmpty()) && (doc->docPatterns.contains(currItem->pattern())))
357 				{
358 					double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
359 					currItem->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
360 					QTransform qmatrix;
361 					qmatrix.translate(patternOffsetX, patternOffsetY);
362 					qmatrix.rotate(patternRotation);
363 					qmatrix.shear(patternSkewX, patternSkewY);
364 					qmatrix.scale(patternScaleX / 100.0, patternScaleY / 100.0);
365 					bool mirrorX, mirrorY;
366 					currItem->patternFlip(mirrorX, mirrorY);
367 					if (mirrorX)
368 						qmatrix.scale(-1, 1);
369 					if (mirrorY)
370 						qmatrix.scale(1, -1);
371 					QImage pat = *doc->docPatterns[currItem->pattern()].getPattern();
372 					QBrush brush = QBrush(pat);
373 					brush.setTransform(qmatrix);
374 					pItem->setBrush(brush);
375 				}
376 			}
377 			else
378 			{
379 				QColor paint = ScColorEngine::getShadeColorProof(doc->PageColors[currItem->fillColor()], doc, currItem->fillShade());
380 				paint.setAlphaF(1.0 - currItem->fillTransparency());
381 				pItem->setBrush(paint);
382 			}
383 		}
384 		if (currItem->isGroup())
385 			pItem->setPen(Qt::NoPen);
386 		else if (currItem->NamedLStyle.isEmpty())
387 		{
388 			if ((!currItem->strokePattern().isEmpty()) && (doc->docPatterns.contains(currItem->strokePattern())))
389 			{
390 				double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace;
391 				currItem->strokePatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace);
392 				QTransform qmatrix;
393 				qmatrix.translate(-currItem->lineWidth() / 2.0, -currItem->lineWidth() / 2.0);
394 				qmatrix.translate(patternOffsetX, patternOffsetY);
395 				qmatrix.rotate(patternRotation);
396 				qmatrix.shear(patternSkewX, patternSkewY);
397 				qmatrix.scale(patternScaleX / 100.0, patternScaleY / 100.0);
398 				bool mirrorX, mirrorY;
399 				currItem->strokePatternFlip(mirrorX, mirrorY);
400 				if (mirrorX)
401 					qmatrix.scale(-1, 1);
402 				if (mirrorY)
403 					qmatrix.scale(1, -1);
404 				QImage pat = *doc->docPatterns[currItem->strokePattern()].getPattern();
405 				QBrush brush = QBrush(pat);
406 				brush.setTransform(qmatrix);
407 				pItem->setPen(QPen(brush, currItem->lineWidth(), currItem->lineStyle(), currItem->lineEnd(), currItem->lineJoin()));
408 			}
409 			else if (currItem->GrTypeStroke > 0)
410 			{
411 				QGradient pat;
412 				double x1 = currItem->GrStrokeStartX;
413 				double y1 = currItem->GrStrokeStartY;
414 				double x2 = currItem->GrStrokeEndX;
415 				double y2 = currItem->GrStrokeEndY;
416 				if (currItem->GrTypeStroke == Gradient_Linear)
417 					pat = QLinearGradient(x1, y1,  x2, y2);
418 				else
419 					pat = QRadialGradient(x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)), x1, y1);
420 				QList<VColorStop*> colorStops = currItem->stroke_gradient.colorStops();
421 				QColor qStopColor;
422 				for (int offset = 0 ; offset < colorStops.count() ; offset++)
423 				{
424 					qStopColor = colorStops[ offset ]->color;
425 					int h, s, v, sneu, vneu;
426 					int shad = colorStops[offset]->shade;
427 					qStopColor.getHsv(&h, &s, &v);
428 					sneu = s * shad / 100;
429 					vneu = 255 - ((255 - v) * shad / 100);
430 					qStopColor.setHsv(h, sneu, vneu);
431 					qStopColor.setAlphaF(colorStops[offset]->opacity);
432 					pat.setColorAt(colorStops[ offset ]->rampPoint, qStopColor);
433 				}
434 				pItem->setPen(QPen(pat, currItem->lineWidth(), currItem->lineStyle(), currItem->lineEnd(), currItem->lineJoin()));
435 			}
436 			else if (currItem->lineColor() != CommonStrings::None)
437 			{
438 				QColor paint = ScColorEngine::getShadeColorProof(doc->PageColors[currItem->lineColor()], doc, currItem->lineShade());
439 				paint.setAlphaF(1.0 - currItem->lineTransparency());
440 				pItem->setPen(QPen(paint, currItem->lineWidth(), currItem->lineStyle(), currItem->lineEnd(), currItem->lineJoin()));
441 			}
442 		}
443 		else
444 		{
445 			if (currItem->lineColor() != CommonStrings::None)
446 			{
447 				QColor paint = ScColorEngine::getShadeColorProof(doc->PageColors[currItem->lineColor()], doc, currItem->lineShade());
448 				paint.setAlphaF(1.0 - currItem->lineTransparency());
449 				pItem->setPen(QPen(paint, currItem->lineWidth(), currItem->lineStyle(), currItem->lineEnd(), currItem->lineJoin()));
450 			}
451 		}
452 		if (currItem->isGroup())
453 		{
454 			pItem->setFlags(QGraphicsItem::ItemClipsChildrenToShape);
455 			Selection tmpSelection(this, false);
456 			for (int a = 0; a < currItem->groupItemList.count(); a++)
457 			{
458 				tmpSelection.addItem(currItem->groupItemList.at(a));
459 			}
460 			addItemsToScene(&tmpSelection, doc, pItem, currItem);
461 		}
462 	}
463 
464 }
465 
showEvent(QShowEvent * e)466 void LensDialog::showEvent(QShowEvent *e)
467 {
468 	QDialog::showEvent(e);
469 	if (isFirst)
470 		previewWidget->fitInView(scene.itemsBoundingRect(), Qt::KeepAspectRatio);
471 	isFirst = false;
472 }
473 
doZoomIn()474 void LensDialog::doZoomIn()
475 {
476 	previewWidget->scale(2.0, 2.0);
477 }
478 
doZoomOut()479 void LensDialog::doZoomOut()
480 {
481 	previewWidget->scale(0.5, 0.5);
482 }
483 
addLens()484 void LensDialog::addLens()
485 {
486 	disconnect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
487 	disconnect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
488 	disconnect(spinRadius, SIGNAL(valueChanged(double)), this, SLOT(setNewLensRadius(double)));
489 	disconnect(spinStrength, SIGNAL(valueChanged(double)), this, SLOT(setNewLensStrength(double)));
490 	disconnect(buttonMagnify, SIGNAL(toggled(bool)), this, SLOT(changeLens()));
491 	if (lensList.count() > 0)
492 	{
493 		lensList[currentLens]->setSelected(false);
494 		lensList[currentLens]->update();
495 	}
496 	QRectF bBox = scene.itemsBoundingRect();
497 	double r = qMin(bBox.width(), bBox.height());
498 	double x = (bBox.width() - r) / 2.0;
499 	double y = (bBox.height() - r) / 2.0;
500 	LensItem *item = new LensItem(QRectF(x, y, r, r), this);
501 	scene.addItem(item);
502 	lensList.append(item);
503 	currentLens = lensList.count() - 1;
504 	item->setZValue(currentLens+999999);
505 	spinXPos->setValue(x + r / 2.0);
506 	spinYPos->setValue(y + r / 2.0);
507 	spinRadius->setValue(r / 2.0);
508 	spinStrength->setValue(100.0);
509 	buttonMagnify->setChecked(true);
510 	lensList[currentLens]->updateEffect();
511 	if (lensList.count() > 1)
512 		buttonRemove->setEnabled(true);
513 	lensList[currentLens]->setSelected(true);
514 	connect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
515 	connect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
516 	connect(spinRadius, SIGNAL(valueChanged(double)), this, SLOT(setNewLensRadius(double)));
517 	connect(spinStrength, SIGNAL(valueChanged(double)), this, SLOT(setNewLensStrength(double)));
518 	connect(buttonMagnify, SIGNAL(toggled(bool)), this, SLOT(changeLens()));
519 }
520 
removeLens()521 void LensDialog::removeLens()
522 {
523 	LensItem *item = lensList.takeAt(currentLens);
524 	scene.removeItem(item);
525 	delete item;
526 	if (lensList.count() > 1)
527 		buttonRemove->setEnabled(true);
528 	else
529 		buttonRemove->setEnabled(false);
530 	currentLens = lensList.count() - 1;
531 	lensList[currentLens]->setSelected(true);
532 	lensList[currentLens]->updateEffect();
533 	lensSelected(lensList[currentLens]);
534 }
535 
changeLens()536 void LensDialog::changeLens()
537 {
538 	double s = qAbs(lensList[currentLens]->strength);
539 	if (buttonMagnify->isChecked())
540 		lensList[currentLens]->setStrength(s * -1.0);
541 	else
542 		lensList[currentLens]->setStrength(s);
543 	lensList[currentLens]->updateEffect();
544 }
545 
selectionHasChanged()546 void LensDialog::selectionHasChanged()
547 {
548 	bool setter = true;
549 	if (scene.selectedItems().count() == 0)
550 		setter = false;
551 	spinXPos->setEnabled(setter);
552 	spinYPos->setEnabled(setter);
553 	spinRadius->setEnabled(setter);
554 	spinStrength->setEnabled(setter);
555 	buttonMagnify->setEnabled(setter);
556 	buttonFishEye->setEnabled(setter);
557 	if (lensList.count() == 1)
558 		buttonRemove->setEnabled(false);
559 	else
560 		buttonRemove->setEnabled(setter);
561 }
562 
lensSelected(LensItem * item)563 void LensDialog::lensSelected(LensItem *item)
564 {
565 	disconnect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
566 	disconnect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
567 	disconnect(spinRadius, SIGNAL(valueChanged(double)), this, SLOT(setNewLensRadius(double)));
568 	disconnect(spinStrength, SIGNAL(valueChanged(double)), this, SLOT(setNewLensStrength(double)));
569 	disconnect(buttonMagnify, SIGNAL(toggled(bool)), this, SLOT(changeLens()));
570 	QPointF p = item->mapToScene(item->rect().center());
571 	spinXPos->setValue(p.x());
572 	spinYPos->setValue(p.y());
573 	spinRadius->setValue(item->rect().width() / 2.0);
574 	if (item->strength < 0.0)
575 		buttonMagnify->setChecked(true);
576 	else
577 		buttonFishEye->setChecked(true);
578 	spinStrength->setValue(qAbs(item->strength));
579 	currentLens = lensList.indexOf(item);
580 	if (currentLens < 0)
581 		currentLens = 0;
582 	connect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
583 	connect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
584 	connect(spinRadius, SIGNAL(valueChanged(double)), this, SLOT(setNewLensRadius(double)));
585 	connect(spinStrength, SIGNAL(valueChanged(double)), this, SLOT(setNewLensStrength(double)));
586 	connect(buttonMagnify, SIGNAL(toggled(bool)), this, SLOT(changeLens()));
587 }
588 
setLensPositionValues(QPointF p)589 void LensDialog::setLensPositionValues(QPointF p)
590 {
591 	disconnect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
592 	disconnect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
593 	spinXPos->setValue(p.x());
594 	spinYPos->setValue(p.y());
595 	connect(spinXPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensX(double)));
596 	connect(spinYPos, SIGNAL(valueChanged(double)), this, SLOT(setNewLensY(double)));
597 }
598 
setNewLensX(double x)599 void LensDialog::setNewLensX(double x)
600 {
601 	QRectF r = lensList[currentLens]->rect();
602 	r.moveCenter(QPointF(x, r.center().y()));
603 	lensList[currentLens]->setRect(r);
604 	lensList[currentLens]->updateEffect();
605 }
606 
setNewLensY(double y)607 void LensDialog::setNewLensY(double y)
608 {
609 	QRectF r = lensList[currentLens]->rect();
610 	r.moveCenter(QPointF(r.center().x(), y));
611 	lensList[currentLens]->setRect(r);
612 	lensList[currentLens]->updateEffect();
613 }
614 
setNewLensRadius(double radius)615 void LensDialog::setNewLensRadius(double radius)
616 {
617 	QRectF r = lensList[currentLens]->rect();
618 	QPointF center = r.center();
619 	r.setWidth(radius * 2.0);
620 	r.setHeight(radius * 2.0);
621 	QPointF centerN = r.center();
622 	r.translate(center.x() - centerN.x(), center.y() - centerN.y());
623 	setLensPositionValues(lensList[currentLens]->mapToScene(r.center()));
624 	lensList[currentLens]->setRect(r);
625 	lensList[currentLens]->updateEffect();
626 }
627 
setNewLensStrength(double s)628 void LensDialog::setNewLensStrength(double s)
629 {
630 	if (buttonMagnify->isChecked())
631 		lensList[currentLens]->setStrength(s * -1.0);
632 	else
633 		lensList[currentLens]->setStrength(s);
634 	lensList[currentLens]->updateEffect();
635 }
636