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 *                                                                         *
9 *   This program is free software; you can redistribute it and/or modify  *
10 *   it under the terms of the GNU General Public License as published by  *
11 *   the Free Software Foundation; either version 2 of the License, or     *
12 *   (at your option) any later version.                                   *
13 *                                                                         *
14 ***************************************************************************/
15 /***************************************************************************
16                  canvasmode_editmeshgradient.cpp  -  description
17                              -------------------
18     begin                : Sat Apr 24 2010
19     copyright            : (C) 2010 by Franz Schmid
20     email                : Franz.Schmid@altmuehlnet.de
21  ***************************************************************************/
22 
23 
24 #include "canvasmode_editmeshgradient.h"
25 
26 #include <QApplication>
27 #include <QButtonGroup>
28 #include <QCheckBox>
29 #include <QCursor>
30 #include <QEvent>
31 #include <QMessageBox>
32 #include <QMouseEvent>
33 #include <QPainterPath>
34 #include <QPoint>
35 #include <QRect>
36 #include <QTimer>
37 #include <QWidgetAction>
38 #include <QDebug>
39 
40 #include "appmodes.h"
41 #include "canvas.h"
42 #include "fpoint.h"
43 #include "fpointarray.h"
44 #include "hyphenator.h"
45 #include "pageitem_textframe.h"
46 #include "prefscontext.h"
47 #include "prefsfile.h"
48 #include "prefsmanager.h"
49 #include "scribus.h"
50 #include "scribusXml.h"
51 #include "scribusdoc.h"
52 #include "scribusview.h"
53 #include "selection.h"
54 #include "ui/aligndistribute.h"
55 #include "ui/contextmenu.h"
56 #include "ui/pageselector.h"
57 #include "ui/propertiespalette.h"
58 #include "undomanager.h"
59 #include "units.h"
60 #include "util.h"
61 #include "util_math.h"
62 
63 
CanvasMode_EditMeshGradient(ScribusView * view)64 CanvasMode_EditMeshGradient::CanvasMode_EditMeshGradient(ScribusView* view) : CanvasMode(view), m_ScMW(view->m_ScMW)
65 {
66 	m_old_mesh = new MeshPoint();
67 }
68 
~CanvasMode_EditMeshGradient()69 CanvasMode_EditMeshGradient::~CanvasMode_EditMeshGradient()
70 {
71 	delete m_old_mesh;
72 	m_old_mesh = nullptr;
73 }
74 
GetItem(PageItem ** pi)75 inline bool CanvasMode_EditMeshGradient::GetItem(PageItem** pi)
76 {
77 	*pi = m_doc->m_Selection->itemAt(0);
78 	return (*pi) != nullptr;
79 }
80 
drawControls(QPainter * p)81 void CanvasMode_EditMeshGradient::drawControls(QPainter* p)
82 {
83 	p->save();
84 	if (m_canvas->m_viewMode.operItemMoving)
85 	{
86 		drawOutline(p);
87 	}
88 	else
89 	{
90 		drawSelection(p, false);
91 	}
92 	if (m_doc->appMode == modeEditMeshGradient)
93 	{
94 		drawControlsMeshGradient(p, m_doc->m_Selection->itemAt(0));
95 	}
96 	p->restore();
97 }
98 
drawControlsMeshGradient(QPainter * psx,PageItem * currItem)99 void CanvasMode_EditMeshGradient::drawControlsMeshGradient(QPainter* psx, PageItem* currItem)
100 {
101 	QPen p1b = QPen(Qt::blue, 1.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
102 	QPen p1bd = QPen(Qt::blue, 1.0 / m_canvas->m_viewMode.scale, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
103 	QPen p8b = QPen(Qt::blue, 8.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
104 	QPen p8r = QPen(Qt::red, 8.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
105 	QPen p8m = QPen(Qt::magenta, 8.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
106 	QPen p14r = QPen(Qt::red, 18.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
107 	QPen p14w = QPen(Qt::white, 18.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
108 	psx->setTransform(currItem->getTransform(), true);
109 	psx->setPen(p1b);
110 	psx->setBrush(Qt::NoBrush);
111 	for (int grow = 0; grow < currItem->meshGradientArray.count()-1; grow++)
112 	{
113 		for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count()-1; gcol++)
114 		{
115 			MeshPoint mp1 = currItem->meshGradientArray[grow][gcol];
116 			MeshPoint mp2 = currItem->meshGradientArray[grow][gcol+1];
117 			MeshPoint mp3 = currItem->meshGradientArray[grow+1][gcol+1];
118 			MeshPoint mp4 = currItem->meshGradientArray[grow+1][gcol];
119 			QPainterPath Bez;
120 			Bez.moveTo(mp1.gridPoint.x(), mp1.gridPoint.y());
121 			Bez.cubicTo(mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
122 			Bez.cubicTo(mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
123 			Bez.cubicTo(mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
124 			Bez.cubicTo(mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
125 			psx->setPen(p1b);
126 			psx->drawPath(Bez);
127 		}
128 	}
129 	for (int grow = 0; grow < currItem->meshGradientArray.count(); grow++)
130 	{
131 		for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count(); gcol++)
132 		{
133 			bool isSelected = false;
134 			for (int se = 0; se < m_selectedMeshPoints.count(); se++)
135 			{
136 				if ((grow == m_selectedMeshPoints[se].first) && (gcol == m_selectedMeshPoints[se].second))
137 				{
138 					isSelected = true;
139 					break;
140 				}
141 			}
142 			MeshPoint mp1 = currItem->meshGradientArray[grow][gcol];
143 			if (m_view->editStrokeGradient == 5)
144 			{
145 				if (isSelected)
146 					psx->setPen(p8r);
147 				else
148 					psx->setPen(p8m);
149 				psx->drawPoint(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()));
150 			}
151 			else if (m_view->editStrokeGradient == 6)
152 			{
153 				if (isSelected)
154 					psx->setPen(p14r);
155 				else
156 					psx->setPen(p14w);
157 				psx->drawPoint(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()));
158 				psx->setPen(QPen(mp1.color, 14.0 / m_canvas->m_viewMode.scale, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin));
159 				psx->drawPoint(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()));
160 				if (isSelected)
161 					psx->setPen(p8r);
162 				else
163 					psx->setPen(p8m);
164 				psx->drawPoint(QPointF(mp1.controlColor.x(), mp1.controlColor.y()));
165 			}
166 			else if (m_view->editStrokeGradient == 7)
167 			{
168 				psx->setPen(p8b);
169 				psx->drawPoint(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()));
170 			}
171 		}
172 	}
173 	if ((m_selectedMeshPoints.count() > 0) && (m_view->editStrokeGradient == 7))
174 	{
175 		int grow = m_selectedMeshPoints[0].first;
176 		int gcol = m_selectedMeshPoints[0].second;
177 		MeshPoint mp1 = currItem->meshGradientArray[grow][gcol];
178 		psx->setPen(p8m);
179 		if (grow == 0)
180 		{
181 			if (gcol == 0)
182 			{
183 				psx->setPen(p1bd);
184 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
185 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
186 				psx->setPen(p8m);
187 				if (m_gradientPoint == useControlR)
188 					psx->setPen(p8r);
189 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
190 				psx->setPen(p8m);
191 				if (m_gradientPoint == useControlB)
192 					psx->setPen(p8r);
193 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
194 			}
195 			else if (gcol == currItem->meshGradientArray[grow].count()-1)
196 			{
197 				psx->setPen(p1bd);
198 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
199 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
200 				psx->setPen(p8m);
201 				if (m_gradientPoint == useControlL)
202 					psx->setPen(p8r);
203 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
204 				psx->setPen(p8m);
205 				if (m_gradientPoint == useControlB)
206 					psx->setPen(p8r);
207 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
208 			}
209 			else
210 			{
211 				psx->setPen(p1bd);
212 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
213 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
214 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
215 				psx->setPen(p8m);
216 				if (m_gradientPoint == useControlL)
217 					psx->setPen(p8r);
218 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
219 				psx->setPen(p8m);
220 				if (m_gradientPoint == useControlB)
221 					psx->setPen(p8r);
222 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
223 				if (m_gradientPoint == useControlR)
224 					psx->setPen(p8r);
225 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
226 			}
227 		}
228 		else if (grow == currItem->meshGradientArray.count()-1)
229 		{
230 			if (gcol == 0)
231 			{
232 				psx->setPen(p1bd);
233 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
234 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
235 				psx->setPen(p8m);
236 				if (m_gradientPoint == useControlR)
237 					psx->setPen(p8r);
238 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
239 				psx->setPen(p8m);
240 				if (m_gradientPoint == useControlT)
241 					psx->setPen(p8r);
242 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
243 			}
244 			else if (gcol == currItem->meshGradientArray[grow].count()-1)
245 			{
246 				psx->setPen(p1bd);
247 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
248 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
249 				psx->setPen(p8m);
250 				if (m_gradientPoint == useControlL)
251 					psx->setPen(p8r);
252 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
253 				psx->setPen(p8m);
254 				if (m_gradientPoint == useControlT)
255 					psx->setPen(p8r);
256 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
257 			}
258 			else
259 			{
260 				psx->setPen(p1bd);
261 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
262 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
263 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
264 				psx->setPen(p8m);
265 				if (m_gradientPoint == useControlL)
266 					psx->setPen(p8r);
267 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
268 				psx->setPen(p8m);
269 				if (m_gradientPoint == useControlT)
270 					psx->setPen(p8r);
271 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
272 				if (m_gradientPoint == useControlR)
273 					psx->setPen(p8r);
274 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
275 			}
276 		}
277 		else
278 		{
279 			if (gcol == 0)
280 			{
281 				psx->setPen(p1bd);
282 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
283 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
284 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
285 				psx->setPen(p8m);
286 				if (m_gradientPoint == useControlR)
287 					psx->setPen(p8r);
288 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
289 				psx->setPen(p8m);
290 				if (m_gradientPoint == useControlT)
291 					psx->setPen(p8r);
292 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
293 				psx->setPen(p8m);
294 				if (m_gradientPoint == useControlB)
295 					psx->setPen(p8r);
296 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
297 			}
298 			else if (gcol == currItem->meshGradientArray[grow].count()-1)
299 			{
300 				psx->setPen(p1bd);
301 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
302 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
303 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
304 				psx->setPen(p8m);
305 				if (m_gradientPoint == useControlL)
306 					psx->setPen(p8r);
307 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
308 				psx->setPen(p8m);
309 				if (m_gradientPoint == useControlT)
310 					psx->setPen(p8r);
311 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
312 				psx->setPen(p8m);
313 				if (m_gradientPoint == useControlB)
314 					psx->setPen(p8r);
315 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
316 			}
317 			else
318 			{
319 				psx->setPen(p1bd);
320 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
321 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
322 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
323 				psx->drawLine(QPointF(mp1.gridPoint.x(), mp1.gridPoint.y()), QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
324 				psx->setPen(p8m);
325 				if (m_gradientPoint == useControlL)
326 					psx->setPen(p8r);
327 				psx->drawPoint(QPointF(mp1.controlLeft.x(), mp1.controlLeft.y()));
328 				psx->setPen(p8m);
329 				if (m_gradientPoint == useControlT)
330 					psx->setPen(p8r);
331 				psx->drawPoint(QPointF(mp1.controlTop.x(), mp1.controlTop.y()));
332 				psx->setPen(p8m);
333 				if (m_gradientPoint == useControlB)
334 					psx->setPen(p8r);
335 				psx->drawPoint(QPointF(mp1.controlBottom.x(), mp1.controlBottom.y()));
336 				psx->setPen(p8m);
337 				if (m_gradientPoint == useControlR)
338 					psx->setPen(p8r);
339 				psx->drawPoint(QPointF(mp1.controlRight.x(), mp1.controlRight.y()));
340 			}
341 		}
342 	}
343 }
344 
enterEvent(QEvent * e)345 void CanvasMode_EditMeshGradient::enterEvent(QEvent *e)
346 {
347 	if (!m_canvas->m_viewMode.m_MouseButtonPressed)
348 	{
349 		setModeCursor();
350 	}
351 }
352 
leaveEvent(QEvent * e)353 void CanvasMode_EditMeshGradient::leaveEvent(QEvent *e)
354 {
355 }
356 
357 
activate(bool fromGesture)358 void CanvasMode_EditMeshGradient::activate(bool fromGesture)
359 {
360 	CanvasMode::activate(fromGesture);
361 
362 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
363 	m_canvas->resetRenderMode();
364 	m_doc->DragP = false;
365 	m_doc->leaveDrag = false;
366 	m_canvas->m_viewMode.operItemMoving = false;
367 	m_canvas->m_viewMode.operItemResizing = false;
368 	m_view->MidButt = false;
369 	m_selectedMeshPoints.clear();
370 	m_keyRepeat = false;
371 	m_Mxp = m_Myp = -1;
372 	setModeCursor();
373 	if (fromGesture)
374 	{
375 		m_view->update();
376 	}
377 }
378 
deactivate(bool forGesture)379 void CanvasMode_EditMeshGradient::deactivate(bool forGesture)
380 {
381 	m_view->setRedrawMarkerShown(false);
382 	m_selectedMeshPoints.clear();
383 	m_gradientPoint = noPointDefined;
384 	m_ScMW->propertiesPalette->updateColorSpecialGradient();
385 
386 	CanvasMode::deactivate(forGesture);
387 }
388 
keyPressEvent(QKeyEvent * e)389 void CanvasMode_EditMeshGradient::keyPressEvent(QKeyEvent *e)
390 {
391 	if (m_selectedMeshPoints.count() == 0)
392 		return;
393 	int kk = e->key();
394 	if (m_keyRepeat)
395 		return;
396 	m_keyRepeat = true;
397 	e->accept();
398 	Qt::KeyboardModifiers buttonModifiers = e->modifiers();
399 	if ((!m_view->m_ScMW->zoomSpinBox->hasFocus()) && (!m_view->m_ScMW->pageSelector->hasFocus()))
400 	{
401 		if (m_doc->m_Selection->count() != 0)
402 		{
403 			double moveBy = 1.0;
404 			double moveX = 0.0;
405 			double moveY = 0.0;
406 			bool isMoving = false;
407 			bool doUpdate = false;
408 			if ((buttonModifiers & Qt::ShiftModifier) && !(buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
409 				moveBy=0.1;
410 			else if (!(buttonModifiers & Qt::ShiftModifier) && (buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
411 				moveBy=10.0;
412 			else if ((buttonModifiers & Qt::ShiftModifier) && (buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
413 				moveBy=0.01;
414 			moveBy/=m_doc->unitRatio();//Lets allow movement by the current doc ratio, not only points
415 			moveBy /= m_canvas->m_viewMode.scale;
416 			PageItem *currItem = m_doc->m_Selection->itemAt(0);
417 			switch (kk)
418 			{
419 				case Qt::Key_7:
420 					moveX = -moveBy;
421 					moveY = -moveBy;
422 					isMoving = true;
423 					doUpdate = true;
424 					break;
425 				case Qt::Key_9:
426 					moveX = moveBy;
427 					moveY = -moveBy;
428 					isMoving = true;
429 					doUpdate = true;
430 					break;
431 				case Qt::Key_3:
432 					moveX = moveBy;
433 					moveY = moveBy;
434 					isMoving = true;
435 					doUpdate = true;
436 					break;
437 				case Qt::Key_1:
438 					moveX = -moveBy;
439 					moveY = moveBy;
440 					isMoving = true;
441 					doUpdate = true;
442 					break;
443 				case Qt::Key_Left:
444 				case Qt::Key_4:
445 					moveX = -moveBy;
446 					isMoving = true;
447 					doUpdate = true;
448 					break;
449 				case Qt::Key_Right:
450 				case Qt::Key_6:
451 					moveX = moveBy;
452 					isMoving = true;
453 					doUpdate = true;
454 					break;
455 				case Qt::Key_Up:
456 				case Qt::Key_8:
457 					moveY = -moveBy;
458 					isMoving = true;
459 					doUpdate = true;
460 					break;
461 				case Qt::Key_Down:
462 				case Qt::Key_2:
463 					moveY = moveBy;
464 					isMoving = true;
465 					doUpdate = true;
466 					break;
467 				case Qt::Key_5:
468 					if (m_view->editStrokeGradient == 6)
469 					{
470 						QPair<int, int> selP = m_selectedMeshPoints[0];
471 						currItem->meshGradientArray[selP.first][selP.second].controlColor = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
472 						doUpdate = true;
473 					}
474 					else if (m_view->editStrokeGradient == 7)
475 					{
476 						QPair<int, int> selP = m_selectedMeshPoints[0];
477 						if (m_gradientPoint == useControlT)
478 							currItem->meshGradientArray[selP.first][selP.second].controlTop = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
479 						else if (m_gradientPoint == useControlB)
480 							currItem->meshGradientArray[selP.first][selP.second].controlBottom = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
481 						else if (m_gradientPoint == useControlL)
482 							currItem->meshGradientArray[selP.first][selP.second].controlLeft = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
483 						else if (m_gradientPoint == useControlR)
484 							currItem->meshGradientArray[selP.first][selP.second].controlRight = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
485 						doUpdate = true;
486 					}
487 					break;
488 			}
489 			if (isMoving)
490 			{
491 				if (m_view->editStrokeGradient == 5)
492 				{
493 					for (int mo = 0; mo < m_selectedMeshPoints.count(); mo++)
494 					{
495 						QPair<int, int> selP = m_selectedMeshPoints[mo];
496 						currItem->meshGradientArray[selP.first][selP.second].moveRel(moveX, moveY);
497 					}
498 				}
499 				else if (m_view->editStrokeGradient == 6)
500 				{
501 					QPair<int, int> selP = m_selectedMeshPoints[0];
502 					currItem->meshGradientArray[selP.first][selP.second].controlColor += FPoint(moveX, moveY);
503 				}
504 				else if (m_view->editStrokeGradient == 7)
505 				{
506 					QPair<int, int> selP = m_selectedMeshPoints[0];
507 					if (m_gradientPoint == useControlT)
508 						currItem->meshGradientArray[selP.first][selP.second].controlTop += FPoint(moveX, moveY);
509 					else if (m_gradientPoint == useControlB)
510 						currItem->meshGradientArray[selP.first][selP.second].controlBottom += FPoint(moveX, moveY);
511 					else if (m_gradientPoint == useControlL)
512 						currItem->meshGradientArray[selP.first][selP.second].controlLeft += FPoint(moveX, moveY);
513 					else if (m_gradientPoint == useControlR)
514 						currItem->meshGradientArray[selP.first][selP.second].controlRight += FPoint(moveX, moveY);
515 				}
516 			}
517 			if (doUpdate)
518 			{
519 				currItem->update();
520 				QRectF upRect;
521 				upRect = QRectF(QPointF(0, 0), QPointF(currItem->width(), currItem->height())).normalized();
522 				upRect.translate(currItem->xPos(), currItem->yPos());
523 				m_doc->regionsChanged()->update(upRect.adjusted(-10.0 - currItem->width() / 2.0, -10.0 - currItem->height() / 2.0, 10.0 + currItem->width() / 2.0, 10.0 + currItem->height() / 2.0));
524 			}
525 		}
526 	}
527 	m_keyRepeat = false;
528 }
529 
mouseDoubleClickEvent(QMouseEvent * m)530 void CanvasMode_EditMeshGradient::mouseDoubleClickEvent(QMouseEvent *m)
531 {
532 	m->accept();
533 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
534 	m_canvas->resetRenderMode();
535 	PageItem *currItem = nullptr;
536 	if ((m_doc->m_Selection->isMultipleSelection()) || (m_doc->appMode != modeNormal))
537 	{
538 		if ((m_doc->m_Selection->isMultipleSelection()) && (m_doc->appMode == modeNormal))
539 		{
540 			if (GetItem(&currItem))
541 			{
542 				/* CB: old code, removing this as shift-alt select on an unselected table selects a cell now.
543 				//#6789 is closed by sorting this.
544 				if (currItem->isTableItem)
545 				{
546 					m_view->Deselect(false);
547 					m_doc->m_Selection->addItem(currItem);
548 					currItem->isSingleSel = true;
549 					//CB FIXME don't call this if the added item is item 0
550 					if (!m_doc->m_Selection->primarySelectionIs(currItem))
551 						currItem->emitAllToGUI();
552 					m_view->updateContents(currItem->getRedrawBounding(m_canvas->scale()));
553 				}*/
554 			}
555 			return;
556 		}
557 		if (!(GetItem(&currItem) && (m_doc->appMode == modeEdit) && currItem->isTextFrame()))
558 		{
559 			mousePressEvent(m);
560 			return;
561 		}
562 	}
563 }
564 
mouseMoveEvent(QMouseEvent * m)565 void CanvasMode_EditMeshGradient::mouseMoveEvent(QMouseEvent *m)
566 {
567 	const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
568 	m->accept();
569 	if (m_selectedMeshPoints.count() == 0)
570 		return;
571 	if (m_canvas->m_viewMode.m_MouseButtonPressed && m_view->moveTimerElapsed())
572 	{
573 		FPoint npfN;
574 		double nx = mousePointDoc.x();
575 		double ny = mousePointDoc.y();
576 		if (!m_doc->ApplyGuides(&nx, &ny) && !m_doc->ApplyGuides(&nx, &ny,true))
577 			npfN = m_doc->ApplyGridF(FPoint(nx, ny));
578 		else
579 			npfN = FPoint(nx, ny);
580 		PageItem *currItem = m_doc->m_Selection->itemAt(0);
581 		QTransform pp = currItem->getTransform();
582 		FPoint npf = npfN.transformPoint(pp, true);
583 		if (m_view->editStrokeGradient == 6)
584 		{
585 			if (m_selectedMeshPoints.count() > 0)
586 			{
587 				QPair<int, int> selP = m_selectedMeshPoints[0];
588 				FPoint cP = currItem->meshGradientArray[selP.first][selP.second].controlColor;
589 				FPoint gP = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
590 				m_canvas->displayXYHUD(m->globalPos(), cP.x() - gP.x(), cP.y() - gP.y());
591 			}
592 		}
593 		else
594 			m_canvas->displayXYHUD(m->globalPos(), npf.x(), npf.y());
595 		FPoint npx(m_Mxp - npfN.x(), m_Myp - npfN.y(), 0, 0, currItem->rotation(), 1, 1, true);
596 		if (m_selectedMeshPoints.count() > 0)
597 		{
598 			if (m_view->editStrokeGradient == 5)
599 			{
600 				for (int mo = 0; mo < m_selectedMeshPoints.count(); mo++)
601 				{
602 					QPair<int, int> selP = m_selectedMeshPoints[mo];
603 					currItem->meshGradientArray[selP.first][selP.second].moveRel(-npx.x(), -npx.y());
604 				}
605 			}
606 			else if (m_view->editStrokeGradient == 6)
607 			{
608 				QPair<int, int> selP = m_selectedMeshPoints[0];
609 				currItem->meshGradientArray[selP.first][selP.second].controlColor -= npx;
610 			}
611 			else if (m_view->editStrokeGradient == 7)
612 			{
613 				QPair<int, int> selP = m_selectedMeshPoints[0];
614 				if (m_gradientPoint == useControlT)
615 					currItem->meshGradientArray[selP.first][selP.second].controlTop -= npx;
616 				else if (m_gradientPoint == useControlB)
617 					currItem->meshGradientArray[selP.first][selP.second].controlBottom -= npx;
618 				else if (m_gradientPoint == useControlL)
619 					currItem->meshGradientArray[selP.first][selP.second].controlLeft -= npx;
620 				else if (m_gradientPoint == useControlR)
621 					currItem->meshGradientArray[selP.first][selP.second].controlRight -= npx;
622 			}
623 			currItem->update();
624 			QTransform itemMatrix = currItem->getTransform();
625 			m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height()));
626 		}
627 		m_Mxp = npfN.x();
628 		m_Myp = npfN.y();
629 	}
630 }
631 
mousePressEvent(QMouseEvent * m)632 void CanvasMode_EditMeshGradient::mousePressEvent(QMouseEvent *m)
633 {
634 	const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos());
635 
636 	m_canvas->PaintSizeRect(QRect());
637 	m_canvas->m_viewMode.m_MouseButtonPressed = true;
638 	m_canvas->m_viewMode.operItemMoving = false;
639 	m_view->HaveSelRect = false;
640 	m_doc->DragP = false;
641 	m_doc->leaveDrag = false;
642 	m->accept();
643 	m_view->registerMousePress(m->globalPos());
644 	m_Mxp = mousePointDoc.x(); //m->x();
645 	m_Myp = mousePointDoc.y(); //m->y();
646 	if (m->button() == Qt::MidButton)
647 	{
648 		m_view->MidButt = true;
649 		if (m->modifiers() & Qt::ControlModifier)
650 			m_view->DrawNew();
651 		return;
652 	}
653 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
654 	QTransform itemMatrix = currItem->getTransform();
655 	bool found = false;
656 	QPair<int, int> selPoint;
657 	if (m_view->editStrokeGradient == 5)
658 	{
659 		m_gradientPoint = noPointDefined;
660 		for (int grow = 0; grow < currItem->meshGradientArray.count(); grow++)
661 		{
662 			for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count(); gcol++)
663 			{
664 				MeshPoint mp = currItem->meshGradientArray[grow][gcol];
665 				QPointF gradientPoint = QPointF(mp.gridPoint.x(), mp.gridPoint.y());
666 				gradientPoint = itemMatrix.map(gradientPoint);
667 				if (m_canvas->hitsCanvasPoint(mousePointDoc, gradientPoint))
668 				{
669 					selPoint.first = grow;
670 					selPoint.second = gcol;
671 					found = true;
672 					*m_old_mesh = mp;
673 					break;
674 				}
675 			}
676 			if (found)
677 				break;
678 		}
679 	}
680 	else if (m_view->editStrokeGradient == 6)
681 	{
682 		m_gradientPoint = noPointDefined;
683 		m_selectedMeshPoints.clear();
684 		for (int grow = 0; grow < currItem->meshGradientArray.count(); grow++)
685 		{
686 			for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count(); gcol++)
687 			{
688 				MeshPoint mp = currItem->meshGradientArray[grow][gcol];
689 				QPointF gradientPoint = QPointF(mp.gridPoint.x(), mp.gridPoint.y());
690 				gradientPoint = itemMatrix.map(gradientPoint);
691 				QPointF gradientColorPoint = QPointF(mp.controlColor.x(), mp.controlColor.y());
692 				gradientColorPoint = itemMatrix.map(gradientColorPoint);
693 				if (m_canvas->hitsCanvasPoint(mousePointDoc, gradientPoint) || m_canvas->hitsCanvasPoint(mousePointDoc, gradientColorPoint))
694 				{
695 					selPoint.first = grow;
696 					selPoint.second = gcol;
697 					currItem->selectedMeshPointX = grow;
698 					currItem->selectedMeshPointY = gcol;
699 					*m_old_mesh = mp;
700 					found = true;
701 					break;
702 				}
703 			}
704 			if (found)
705 				break;
706 		}
707 	}
708 	else if (m_view->editStrokeGradient == 7)
709 	{
710 		for (int grow = 0; grow < currItem->meshGradientArray.count(); grow++)
711 		{
712 			for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count(); gcol++)
713 			{
714 				MeshPoint mp1 = currItem->meshGradientArray[grow][gcol];
715 				QPointF gradientPoint;
716 				if (grow == 0)
717 				{
718 					if (gcol == 0)
719 					{
720 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
721 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
722 						{
723 							m_gradientPoint = useControlR;
724 							found = true;
725 						}
726 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
727 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
728 						{
729 							m_gradientPoint = useControlB;
730 							found = true;
731 						}
732 					}
733 					else if (gcol == currItem->meshGradientArray[grow].count()-1)
734 					{
735 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
736 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
737 						{
738 							m_gradientPoint = useControlL;
739 							found = true;
740 						}
741 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
742 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
743 						{
744 							m_gradientPoint = useControlB;
745 							found = true;
746 						}
747 					}
748 					else
749 					{
750 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
751 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
752 						{
753 							m_gradientPoint = useControlL;
754 							found = true;
755 						}
756 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
757 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
758 						{
759 							m_gradientPoint = useControlR;
760 							found = true;
761 						}
762 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
763 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
764 						{
765 							m_gradientPoint = useControlB;
766 							found = true;
767 						}
768 					}
769 				}
770 				else if (grow == currItem->meshGradientArray.count()-1)
771 				{
772 					if (gcol == 0)
773 					{
774 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
775 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
776 						{
777 							m_gradientPoint = useControlR;
778 							found = true;
779 						}
780 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
781 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
782 						{
783 							m_gradientPoint = useControlT;
784 							found = true;
785 						}
786 					}
787 					else if (gcol == currItem->meshGradientArray[grow].count()-1)
788 					{
789 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
790 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
791 						{
792 							m_gradientPoint = useControlT;
793 							found = true;
794 						}
795 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
796 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
797 						{
798 							m_gradientPoint = useControlL;
799 							found = true;
800 						}
801 					}
802 					else
803 					{
804 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
805 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
806 						{
807 							m_gradientPoint = useControlT;
808 							found = true;
809 						}
810 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
811 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
812 						{
813 							m_gradientPoint = useControlL;
814 							found = true;
815 						}
816 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
817 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
818 						{
819 							m_gradientPoint = useControlR;
820 							found = true;
821 						}
822 					}
823 				}
824 				else
825 				{
826 					if (gcol == 0)
827 					{
828 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
829 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
830 						{
831 							m_gradientPoint = useControlB;
832 							found = true;
833 						}
834 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
835 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
836 						{
837 							m_gradientPoint = useControlT;
838 							found = true;
839 						}
840 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
841 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
842 						{
843 							m_gradientPoint = useControlR;
844 							found = true;
845 						}
846 					}
847 					else if (gcol == currItem->meshGradientArray[grow].count()-1)
848 					{
849 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
850 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
851 						{
852 							m_gradientPoint = useControlB;
853 							found = true;
854 						}
855 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
856 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
857 						{
858 							m_gradientPoint = useControlT;
859 							found = true;
860 						}
861 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
862 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
863 						{
864 							m_gradientPoint = useControlL;
865 							found = true;
866 						}
867 					}
868 					else
869 					{
870 						gradientPoint = QPointF(mp1.controlBottom.x(), mp1.controlBottom.y());
871 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
872 						{
873 							m_gradientPoint = useControlB;
874 							found = true;
875 						}
876 						gradientPoint = QPointF(mp1.controlTop.x(), mp1.controlTop.y());
877 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
878 						{
879 							m_gradientPoint = useControlT;
880 							found = true;
881 						}
882 						gradientPoint = QPointF(mp1.controlLeft.x(), mp1.controlLeft.y());
883 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
884 						{
885 							m_gradientPoint = useControlL;
886 							found = true;
887 						}
888 						gradientPoint = QPointF(mp1.controlRight.x(), mp1.controlRight.y());
889 						if (m_canvas->hitsCanvasPoint(mousePointDoc, itemMatrix.map(gradientPoint)))
890 						{
891 							m_gradientPoint = useControlR;
892 							found = true;
893 						}
894 					}
895 				}
896 				if (found)
897 				{
898 					selPoint.first = grow;
899 					selPoint.second = gcol;
900 					*m_old_mesh = mp1;
901 					break;
902 				}
903 			}
904 			if (found)
905 				break;
906 		}
907 		if (!found)
908 		{
909 			for (int grow = 0; grow < currItem->meshGradientArray.count(); grow++)
910 			{
911 				for (int gcol = 0; gcol < currItem->meshGradientArray[grow].count(); gcol++)
912 				{
913 					MeshPoint mp = currItem->meshGradientArray[grow][gcol];
914 					QPointF gradientPoint = QPointF(mp.gridPoint.x(), mp.gridPoint.y());
915 					gradientPoint = itemMatrix.map(gradientPoint);
916 					if (m_canvas->hitsCanvasPoint(mousePointDoc, gradientPoint))
917 					{
918 						selPoint.first = grow;
919 						selPoint.second = gcol;
920 						m_gradientPoint = noPointDefined;
921 						found = true;
922 						break;
923 					}
924 				}
925 				if (found)
926 					break;
927 			}
928 		}
929 	}
930 	if (!found)
931 	{
932 		if (!(m->modifiers() & Qt::ShiftModifier))
933 		{
934 			m_gradientPoint = noPointDefined;
935 			m_selectedMeshPoints.clear();
936 			currItem->selectedMeshPointX = -1;
937 			currItem->selectedMeshPointY = -1;
938 			currItem->selectedMeshControlPoint = static_cast<int>(m_gradientPoint);
939 		}
940 	}
941 	else
942 	{
943 		bool isSelected = false;
944 		for (int se = 0; se < m_selectedMeshPoints.count(); se++)
945 		{
946 			if ((selPoint.first == m_selectedMeshPoints[se].first) && (selPoint.second == m_selectedMeshPoints[se].second))
947 			{
948 				isSelected = true;
949 				break;
950 			}
951 		}
952 		if ((!(m->modifiers() & Qt::ShiftModifier)) && (!isSelected))
953 			m_selectedMeshPoints.clear();
954 		if (!isSelected)
955 			m_selectedMeshPoints.append(selPoint);
956 		currItem->selectedMeshPointX = m_selectedMeshPoints[0].first;
957 		currItem->selectedMeshPointY = m_selectedMeshPoints[0].second;
958 		currItem->selectedMeshControlPoint = static_cast<int>(m_gradientPoint);
959 	}
960 	m_canvas->m_viewMode.m_MouseButtonPressed = true;
961 	m_ScMW->propertiesPalette->updateColorSpecialGradient();
962 	m_view->setCursor(QCursor(Qt::CrossCursor));
963 	m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height()));
964 }
965 
mouseReleaseEvent(QMouseEvent * m)966 void CanvasMode_EditMeshGradient::mouseReleaseEvent(QMouseEvent *m)
967 {
968 	m_canvas->m_viewMode.m_MouseButtonPressed = false;
969 	m_canvas->resetRenderMode();
970 	m->accept();
971 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
972 	if (currItem->selectedMeshPointX >=0 && currItem->selectedMeshPointY >=0 && UndoManager::undoEnabled())
973 	{
974 		ScItemState<QPair<MeshPoint,MeshPoint> > *ss = new ScItemState<QPair<MeshPoint,MeshPoint> >(Um::GradPos);
975 		ss->set("MOVE_MESH_PATCH");
976 		ss->set("ARRAY",true);
977 		ss->set("X",currItem->selectedMeshPointX);
978 		ss->set("Y",currItem->selectedMeshPointY);
979 		if ((*m_old_mesh) == currItem->meshGradientArray[currItem->selectedMeshPointX][currItem->selectedMeshPointY])
980 		{
981 			delete ss;
982 			ss=nullptr;
983 		}
984 		else
985 			ss->setItem(qMakePair(*m_old_mesh,currItem->meshGradientArray[currItem->selectedMeshPointX][currItem->selectedMeshPointY]));
986 		if (ss)
987 			undoManager->action(currItem,ss);
988 	}
989 	currItem->update();
990 	QTransform itemMatrix = currItem->getTransform();
991 	m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height()));
992 }
993