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                           pageitem.cpp  -  description
9                              -------------------
10     begin                : Sat Apr 7 2001
11     copyright            : (C) 2001 by Franz Schmid
12     email                : Franz.Schmid@altmuehlnet.de
13  ***************************************************************************/
14 
15 /***************************************************************************
16  *                                                                         *
17  *   This program is free software; you can redistribute it and/or modify  *
18  *   it under the terms of the GNU General Public License as published by  *
19  *   the Free Software Foundation; either version 2 of the License, or     *
20  *   (at your option) any later version.                                   *
21  *                                                                         *
22  ***************************************************************************/
23 
24 #include "pageitem.h"
25 
26 #include <QDebug>
27 #include <QFileInfo>
28 #include <QFont>
29 #include <QMessageBox>
30 #include <QPainter>
31 #include <QPen>
32 #include <QPoint>
33 #include <QPointF>
34 #include <QPolygon>
35 #include <QRegExp>
36 #include <QRegion>
37 #include <QRegularExpression>
38 #include <cairo.h>
39 #include <cassert>
40 #include <qdrawutil.h>
41 #include <sstream>
42 
43 #include "appmodes.h"
44 #include "canvas.h"
45 #include "canvasmode.h"
46 #include "cmsettings.h"
47 #include "colorblind.h"
48 #include "desaxe/saxXML.h"
49 #include "iconmanager.h"
50 #include "marks.h"
51 #include "pageitem_arc.h"
52 #include "pageitem_group.h"
53 #include "pageitem_latexframe.h"
54 #include "pageitem_line.h"
55 #include "pageitem_noteframe.h"
56 #include "pageitem_regularpolygon.h"
57 #include "pageitem_spiral.h"
58 #include "pageitem_table.h"
59 #include "pageitem_textframe.h"
60 #include "prefsmanager.h"
61 #include "resourcecollection.h"
62 #include "scclocale.h"
63 #include "sccolorengine.h"
64 #include "scimagecacheproxy.h"
65 #include "sclimits.h"
66 #include "scpage.h"
67 #include "scpainter.h"
68 #include "scpaths.h"
69 #include "scpattern.h"
70 #include "scribusapp.h"
71 #include "scribuscore.h"
72 #include "scribusdoc.h"
73 #include "scribusview.h"
74 #include "scribuswin.h"
75 #include "sctextstream.h"
76 #include "selection.h"
77 #include "text/storytext.h"
78 #include "ui/contentpalette.h"
79 #include "ui/guidemanager.h"
80 #include "ui/propertiespalette.h"
81 #include "undomanager.h"
82 #include "undostate.h"
83 #include "units.h"
84 #include "util.h"
85 #include "util_file.h"
86 #include "util_formats.h"
87 #include "util_math.h"
88 #include "util_text.h"
89 
90 
91 
92 
93 using namespace std;
94 
PageItem(const PageItem & other)95 PageItem::PageItem(const PageItem & other)
96 	: QObject(other.parent()),
97 	 UndoObject(other),
98 	 SingleObservable<PageItem>(other.m_Doc->itemsChanged()),
99 	 TextContext(this),
100 
101 // 200 attributes! That is madness, or to quote some famous people from Kriquet:
102 // "THAT ALL HAS TO GO!"
103 	gXpos(other.gXpos),
104 	gYpos(other.gYpos),
105 	gWidth(other.gWidth),
106 	gHeight(other.gHeight),
107 	GrType(other.GrType),
108 	GrStartX(other.GrStartX),
109 	GrStartY(other.GrStartY),
110 	GrEndX(other.GrEndX),
111 	GrEndY(other.GrEndY),
112 	GrFocalX(other.GrFocalX),
113 	GrFocalY(other.GrFocalY),
114 	GrScale(other.GrScale),
115 	GrSkew(other.GrSkew),
116 	GrExtend(other.GrExtend),
117 	GrControl1(other.GrControl1),
118 	GrControl2(other.GrControl2),
119 	GrControl3(other.GrControl3),
120 	GrControl4(other.GrControl4),
121 	GrControl5(other.GrControl5),
122 	GrColorP1(other.GrColorP1),
123 	GrColorP2(other.GrColorP2),
124 	GrColorP3(other.GrColorP3),
125 	GrColorP4(other.GrColorP4),
126 	GrCol1transp(other.GrCol1transp),
127 	GrCol2transp(other.GrCol2transp),
128 	GrCol3transp(other.GrCol3transp),
129 	GrCol4transp(other.GrCol4transp),
130 	GrCol1Shade(other.GrCol1Shade),
131 	GrCol2Shade(other.GrCol2Shade),
132 	GrCol3Shade(other.GrCol3Shade),
133 	GrCol4Shade(other.GrCol4Shade),
134 	meshGradientPatches(other.meshGradientPatches),
135 	meshGradientArray(other.meshGradientArray),
136 	selectedMeshPointX(other.selectedMeshPointX),
137 	selectedMeshPointY(other.selectedMeshPointY),
138 	selectedMeshControlPoint(other.selectedMeshControlPoint),
139 	snapToPatchGrid(other.snapToPatchGrid),
140 	m_columns(other.m_columns),
141 	m_columnGap(other.m_columnGap),
142 	PLineArt(other.PLineArt),
143 	PLineEnd(other.PLineEnd),
144 	PLineJoin(other.PLineJoin),
145 	NamedLStyle(other.NamedLStyle),
146 	Clip(other.Clip),
147 	PoLine(other.PoLine),
148 	ContourLine(other.ContourLine),
149 	imageClip(other.imageClip),
150 	Segments(other.Segments),
151 	effectsInUse(other.effectsInUse),
152 	PoShow(other.PoShow),
153 	BaseOffs(other.BaseOffs),
154 	textPathType(other.textPathType),
155 	textPathFlipped(other.textPathFlipped),
156 	ClipEdited(other.ClipEdited),
157 	FrameType(other.FrameType),
158 	OwnPage(other.OwnPage),
159 	oldOwnPage(other.oldOwnPage),
160 	pixm(other.pixm),
161 	Pfile(other.Pfile),
162 	Pfile2(other.Pfile2),
163 	Pfile3(other.Pfile3),
164 	ImageProfile(other.ImageProfile),
165 	UseEmbedded(other.UseEmbedded),
166 	EmbeddedProfile(other.EmbeddedProfile),
167 	ImageIntent(other.ImageIntent),
168 	OverrideCompressionMethod(other.OverrideCompressionMethod),
169 	CompressionMethodIndex(other.CompressionMethodIndex),
170 	OverrideCompressionQuality(other.OverrideCompressionQuality),
171 	CompressionQualityIndex(other.CompressionQualityIndex),
172 
173 	imageIsAvailable(other.imageIsAvailable),
174 	OrigW(other.OrigW),
175 	OrigH(other.OrigH),
176 	BBoxX(other.BBoxX),
177 	BBoxH(other.BBoxH),
178 	CurX(other.CurX),
179 	CurY(other.CurY),
180 	itemText(other.itemText),
181 	textLayout(&itemText, this),
182 	isBookmark(other.isBookmark),
183 	HasSel(other.HasSel),
184 	isAutoText(other.isAutoText),
185 	inPdfArticle(other.inPdfArticle),
186 	isRaster(other.isRaster),
187 	OldB(other.OldB),
188 	OldH(other.OldH),
189 	OldB2(other.OldB2),
190 	OldH2(other.OldH2),
191 	Sizing(other.Sizing),
192 	m_layerID(other.m_layerID),
193 	ScaleType(other.ScaleType),
194 	AspectRatio(other.AspectRatio),
195 	DashValues(other.DashValues),
196 	DashOffset(other.DashOffset),
197 	fill_gradient(other.fill_gradient),
198 	fillRule(other.fillRule),
199 	doOverprint(other.doOverprint),
200 	m_leftLink(other.m_leftLink),
201 	m_rightLink(other.m_rightLink),
202 	m_topLink(other.m_topLink),
203 	m_bottomLink(other.m_bottomLink),
204 	LeftLinkID(other.LeftLinkID),
205 	RightLinkID(other.RightLinkID),
206 	TopLinkID(other.TopLinkID),
207 	BottomLinkID(other.BottomLinkID),
208 	LeftLine(other.LeftLine),
209 	RightLine(other.RightLine),
210 	TopLine(other.TopLine),
211 	BottomLine(other.BottomLine),
212 	isTableItem(other.isTableItem),
213 	isSingleSel(other.isSingleSel),
214 	groupItemList(other.groupItemList),
215 	groupWidth(other.groupWidth),
216 	groupHeight(other.groupHeight),
217 	BoundingX(other.BoundingX),
218 	BoundingY(other.BoundingY),
219 	BoundingW(other.BoundingW),
220 	BoundingH(other.BoundingH),
221 	ChangedMasterItem(other.ChangedMasterItem),
222 	OnMasterPage(other.OnMasterPage),
223 	isEmbedded(other.isEmbedded),
224 	m_roundedCornerRadius(other.m_roundedCornerRadius),
225 	oldXpos(other.oldXpos),
226 	oldYpos(other.oldYpos),
227 	oldWidth(other.oldWidth),
228 	oldHeight(other.oldHeight),
229 	oldRot(other.oldRot),
230 	oldLocalScX(other.oldLocalScX),
231 	oldLocalScY(other.oldLocalScY),
232 	oldLocalX(other.oldLocalX),
233 	oldLocalY(other.oldLocalY),
234 	m_Doc(other.m_Doc),
235 	m_lineWidth(other.m_lineWidth),
236 	m_oldLineWidth(other.m_oldLineWidth),
237 	patternStrokeVal(other.patternStrokeVal),
238 	patternStrokeScaleX(other.patternStrokeScaleX),
239 	patternStrokeScaleY(other.patternStrokeScaleY),
240 	patternStrokeOffsetX(other.patternStrokeOffsetX),
241 	patternStrokeOffsetY(other.patternStrokeOffsetY),
242 	patternStrokeRotation(other.patternStrokeRotation),
243 	patternStrokeSkewX(other.patternStrokeSkewX),
244 	patternStrokeSkewY(other.patternStrokeSkewY),
245 	patternStrokeSpace(other.patternStrokeSpace),
246 	patternStrokeMirrorX(other.patternStrokeMirrorX),
247 	patternStrokeMirrorY(other.patternStrokeMirrorY),
248 	patternStrokePath(other.patternStrokePath),
249 	gradientStrokeVal(other.gradientStrokeVal),
250 	stroke_gradient(other.stroke_gradient),
251 	GrTypeStroke(other.GrTypeStroke),
252 	GrStrokeStartX(other.GrStrokeStartX),
253 	GrStrokeStartY(other.GrStrokeStartY),
254 	GrStrokeEndX(other.GrStrokeEndX),
255 	GrStrokeEndY(other.GrStrokeEndY),
256 	GrStrokeFocalX(other.GrStrokeFocalX),
257 	GrStrokeFocalY(other.GrStrokeFocalY),
258 	GrStrokeScale(other.GrStrokeScale),
259 	GrStrokeSkew(other.GrStrokeSkew),
260 	GrMask(other.GrMask),
261 	GrMaskStartX(other.GrMaskStartX),
262 	GrMaskStartY(other.GrMaskStartY),
263 	GrMaskEndX(other.GrMaskEndX),
264 	GrMaskEndY(other.GrMaskEndY),
265 	GrMaskFocalX(other.GrMaskFocalX),
266 	GrMaskFocalY(other.GrMaskFocalY),
267 	GrMaskScale(other.GrMaskScale),
268 	GrMaskSkew(other.GrMaskSkew),
269 	patternMaskScaleX(other.patternMaskScaleX),
270 	patternMaskScaleY(other.patternMaskScaleY),
271 	patternMaskOffsetX(other.patternMaskOffsetX),
272 	patternMaskOffsetY(other.patternMaskOffsetY),
273 	patternMaskRotation(other.patternMaskRotation),
274 	patternMaskSkewX(other.patternMaskSkewX),
275 	patternMaskSkewY(other.patternMaskSkewY),
276 	patternMaskMirrorX(other.patternMaskMirrorX),
277 	patternMaskMirrorY(other.patternMaskMirrorY),
278 	patternMaskVal(other.patternMaskVal),
279 	mask_gradient(other.mask_gradient),
280 	hatchAngle(other.hatchAngle),
281 	hatchDistance(other.hatchDistance),
282 	hatchType(other.hatchType),
283 	hatchUseBackground(other.hatchUseBackground),
284 	hatchBackground(other.hatchBackground),
285 	hatchForeground(other.hatchForeground),
286 	hatchBackgroundQ(other.hatchBackgroundQ),
287 	hatchForegroundQ(other.hatchForegroundQ),
288 	// protected
289 	undoManager(other.undoManager),
290 	firstChar(0),   // since this box is unlinked now
291 	m_maxChars(0),   // since the layout is invalid now
292 	m_sampleItem(false),
293 	m_textDistanceMargins(other.m_textDistanceMargins),
294 	verticalAlign(other.verticalAlign),
295 	m_itemType(other.m_itemType),
296 	m_itemName(other.m_itemName),
297 	m_isAnnotation(other.m_isAnnotation),
298 	m_annotation(other.m_annotation),
299 	m_gradientName(other.m_gradientName),
300 	m_patternName(other.m_patternName),
301 	patternScaleX(other.patternScaleX),
302 	patternScaleY(other.patternScaleY),
303 	patternOffsetX(other.patternOffsetX),
304 	patternOffsetY(other.patternOffsetY),
305 	patternRotation(other.patternRotation),
306 	patternSkewX(other.patternSkewX),
307 	patternSkewY(other.patternSkewY),
308 	patternMirrorX(other.patternMirrorX),
309 	patternMirrorY(other.patternMirrorY),
310 	m_fillColor(other.m_fillColor),
311 	m_lineColor(other.m_lineColor),
312 	m_lineShade(other.m_lineShade),
313 	m_fillShade(other.m_fillShade),
314 	m_fillTransparency(other.m_fillTransparency),
315 	m_lineTransparency(other.m_lineTransparency),
316 	m_fillBlendMode(other.m_fillBlendMode),
317 	m_lineBlendMode(other.m_lineBlendMode),
318 	m_ImageIsFlippedH(other.m_ImageIsFlippedH),
319 	m_ImageIsFlippedV(other.m_ImageIsFlippedV),
320 	m_Locked(other.m_Locked),
321 	m_SizeLocked(other.m_SizeLocked),
322 	m_SizeHLocked(other.m_SizeHLocked),
323 	m_SizeVLocked(other.m_SizeVLocked),
324 	m_textFlowMode(other.m_textFlowMode),
325 	pageItemAttributes(other.pageItemAttributes),
326 	m_PrintEnabled(other.m_PrintEnabled),
327 	m_fillQColor(other.m_fillQColor),
328 	m_strokeQColor(other.m_strokeQColor),
329 	m_grQColorP1(other.m_grQColorP1),
330 	m_grQColorP2(other.m_grQColorP2),
331 	m_grQColorP3(other.m_grQColorP3),
332 	m_grQColorP4(other.m_grQColorP4),
333 	m_xPos(other.m_xPos),
334 	m_yPos(other.m_yPos),
335 	m_width(other.m_width),
336 	m_height(other.m_height),
337 	m_rotation(other.m_rotation),
338 	m_isSelected(other.m_isSelected),
339 	m_imageVisible(other.m_imageVisible),
340 	m_imageXScale(other.m_imageXScale),
341 	m_imageYScale(other.m_imageYScale),
342 	m_imageXOffset(other.m_imageXOffset),
343 	m_imageYOffset(other.m_imageYOffset),
344 	m_imageRotation(other.m_imageRotation),
345 	m_firstLineOffset(other.m_firstLineOffset),
346 	m_groupClips(other.m_groupClips),
347 	m_startArrowIndex(other.m_startArrowIndex),
348 	m_endArrowIndex(other.m_endArrowIndex),
349 	m_startArrowScale(other.m_startArrowScale),
350 	m_endArrowScale(other.m_endArrowScale),
351 	m_hasSoftShadow(other.m_hasSoftShadow),
352 	m_softShadowColor(other.m_softShadowColor),
353 	m_softShadowShade(other.m_softShadowShade),
354 	m_softShadowBlurRadius(other.m_softShadowBlurRadius),
355 	m_softShadowXOffset(other.m_softShadowXOffset),
356 	m_softShadowYOffset(other.m_softShadowYOffset),
357 	m_softShadowOpacity(other.m_softShadowOpacity),
358 	m_softShadowBlendMode(other.m_softShadowBlendMode),
359 	m_softShadowErasedByObject(other.m_softShadowErasedByObject),
360 	m_softShadowHasObjectTransparency(other.m_softShadowHasObjectTransparency)
361 {
362 	QString tmp;
363 	m_imageVisible = m_Doc->guidesPrefs().showPic;
364 	m_Doc->TotalItems++;
365 
366 	QString oldName(m_itemName);
367 	int nameNum = m_Doc->TotalItems;
368 	m_itemName += tmp.setNum(m_Doc->TotalItems);
369 	while (m_Doc->itemNameExists(m_itemName))
370 	{
371 		++nameNum;
372 		m_itemName = oldName + tmp.setNum(nameNum);
373 	}
374 
375 	uniqueNr = m_Doc->TotalItems;
376 	invalid = true;
377 	if (other.isInlineImage)
378 	{
379 		QFileInfo inlFi(Pfile);
380 		QString ext = inlFi.suffix();
381 		QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + ext);
382 		tempFile->setAutoRemove(false);
383 		tempFile->open();
384 		QString fileName = getLongPathName(tempFile->fileName());
385 		tempFile->close();
386 		copyFile(Pfile, fileName);
387 		Pfile = fileName;
388 		delete tempFile;
389 		isInlineImage = true;
390 		isTempFile = true;
391 	}
392 	else
393 	{
394 		isInlineImage = false;
395 		isTempFile = false;
396 	}
397 	Parent = nullptr;
398 	unWeld();
399 }
400 
401 
PageItem(ScribusDoc * doc,ItemType newType,double x,double y,double w,double h,double w2,const QString & fill,const QString & outline)402 PageItem::PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
403 	// Initialize superclass(es)
404 	: QObject(doc), SingleObservable<PageItem>(doc->itemsChanged()), TextContext(this),
405 	// Initialize member variables
406 	itemText(doc),
407 	textLayout(&itemText, this),
408 	undoManager(UndoManager::instance())
409 {
410 	m_Doc = doc;
411 	QString tmp;
412 	gXpos = oldXpos = m_xPos = x;
413 	gYpos = oldYpos = m_yPos = y;
414 	//CB Surely we can remove some of these?
415 	OldB2 = OldB = oldWidth = m_width = w;
416 	OldH2 = OldH = oldHeight = m_height = h;
417 	BoundingX = x;
418 	BoundingY = y;
419 	BoundingW = w;
420 	BoundingH = h;
421 	m_itemType = newType;
422 	m_fillColor = fill;
423 	m_lineColor = m_itemType == PageItem::TextFrame ? fill : outline;
424 	GrEndX = w;
425 
426 	GrControl2 = FPoint(w, 0);
427 	GrControl3 = FPoint(w, h);
428 	GrControl4 = FPoint(0, h);
429 	GrControl5 = FPoint(w / 2.0, h / 2.0);
430 	GrStrokeEndX = w;
431 	m_lineWidth = w2;
432 	m_oldLineWidth = w2;
433 	PLineArt = Qt::PenStyle(m_Doc->itemToolPrefs().shapeLineStyle);
434 	PLineEnd = Qt::FlatCap;
435 	PLineJoin = Qt::MiterJoin;
436 	m_textDistanceMargins = m_Doc->itemToolPrefs().textDistances;
437 	pixm.imgInfo.lowResType = m_Doc->itemToolPrefs().imageLowResType;
438 	switch (m_itemType)
439 	{
440 		case Polygon:
441 			Clip.setPoints(4, static_cast<int>(w / 2), 0, static_cast<int>(w), static_cast<int>(h / 2),
442 								static_cast<int>(w / 2), static_cast<int>(h), 0, static_cast<int>(h / 2));
443 			break;
444 		default:
445 			Clip.setPoints(4, 0, 0, static_cast<int>(w), 0, static_cast<int>(w), static_cast<int>(h), 0, static_cast<int>(h));
446 			break;
447 	}
448 	OwnPage = m_Doc->currentPage() ? m_Doc->currentPage()->pageNr() : -1;
449 	oldOwnPage = OwnPage;
450 	savedOwnPage = OwnPage;
451 	m_imageVisible = m_Doc->guidesPrefs().showPic;
452 
453 	switch (m_itemType)
454 	{
455 		case ImageFrame:
456 		case OSGFrame:
457 		case LatexFrame:
458 			//We can't determine if this is a latex frame here
459 			// because c++'s typeinfos are still saying it's
460 			// a plain pageitem
461 			// This is fixed in the PageItem_LatexFrame constructor
462 			m_itemName = tr("Image");
463 			setUPixmap(Um::IImageFrame);
464 			break;
465 		case TextFrame:
466 			m_itemName = tr("Text");
467 			setUPixmap(Um::ITextFrame);
468 			break;
469 		case Line:
470 			m_itemName = tr("Line");
471 			setUPixmap(Um::ILine);
472 			break;
473 		case Polygon:
474 			m_itemName = tr("Polygon");
475 			setUPixmap(Um::IPolygon);
476 			break;
477 		case PolyLine:
478 			m_itemName = tr("Polyline");
479 			setUPixmap(Um::IPolyline);
480 			break;
481 		case PathText:
482 			m_itemName = tr("PathText");
483 			setUPixmap(Um::IPathText);
484 			break;
485 		case Symbol:
486 			m_itemName = tr("Symbol");
487 			setUPixmap(Um::IPolygon);
488 			break;
489 		case Group:
490 			m_itemName = tr("Group");
491 			setUPixmap(Um::IPolygon);
492 			break;
493 		case RegularPolygon:
494 			m_itemName = tr("RegularPolygon");
495 			setUPixmap(Um::IPolygon);
496 			break;
497 		case Arc:
498 			m_itemName = tr("Arc");
499 			setUPixmap(Um::IPolygon);
500 			break;
501 		case Spiral:
502 			m_itemName = tr("Spiral");
503 			setUPixmap(Um::IPolygon);
504 			break;
505 		case Table:
506 			m_itemName = tr("Table");
507 			//setUPixmap(Um::IPolygon); // TODO: Fix this.
508 			break;
509 		default:
510 			m_itemName = "Item";
511 			break;
512 	}
513 	m_Doc->TotalItems++;
514 
515 	QString oldName(m_itemName);
516 	int nameNum = m_Doc->TotalItems;
517 	m_itemName += tmp.setNum(m_Doc->TotalItems);
518 	while (m_Doc->itemNameExists(m_itemName))
519 	{
520 		++nameNum;
521 		m_itemName = oldName + tmp.setNum(nameNum);
522 	}
523 
524 	uniqueNr = m_Doc->TotalItems;
525 	setUName(m_itemName);
526 	m_annotation.setBorderColor(outline);
527 //	toPixmap = false;
528 	ImageIntent = Intent_Relative_Colorimetric;
529 	m_layerID = m_Doc->activeLayer();
530 	stroke_gradient = VGradient(VGradient::linear);
531 	stroke_gradient.clearStops();
532 	if (m_lineColor != CommonStrings::None)
533 	{
534 		const ScColor& col = m_Doc->PageColors[m_lineColor];
535 		QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
536 		stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_lineColor, 100);
537 		stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_lineColor, 100);
538 	}
539 	else
540 	{
541 		if (m_Doc->itemToolPrefs().shapeLineColor != CommonStrings::None)
542 		{
543 			const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeLineColor];
544 			QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
545 			stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
546 			stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
547 		}
548 		else
549 		{
550 			if (m_fillColor != CommonStrings::None)
551 			{
552 				const ScColor& col = m_Doc->PageColors[m_fillColor];
553 				QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
554 				stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_fillColor, 100);
555 				stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_fillColor, 100);
556 			}
557 			else
558 			{
559 				if (m_Doc->itemToolPrefs().shapeFillColor != CommonStrings::None)
560 				{
561 					const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeFillColor];
562 					QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
563 					stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
564 					stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
565 				}
566 				else if (m_Doc->PageColors.contains("Black"))
567 				{
568 					const ScColor& col = m_Doc->PageColors["Black"];
569 					QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
570 					stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
571 					stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
572 				}
573 			}
574 		}
575 	}
576 	fill_gradient = VGradient(VGradient::linear);
577 	fill_gradient.clearStops();
578 	if (m_fillColor != CommonStrings::None)
579 	{
580 		const ScColor& col = m_Doc->PageColors[m_fillColor];
581 		QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
582 		fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_fillColor, 100);
583 		fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_fillColor, 100);
584 		GrColorP1 = m_fillColor;
585 		GrColorP2 = m_fillColor;
586 		GrColorP3 = m_fillColor;
587 		GrColorP4 = m_fillColor;
588 	}
589 	else
590 	{
591 		if (m_Doc->itemToolPrefs().shapeFillColor != CommonStrings::None)
592 		{
593 			const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeFillColor];
594 			QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
595 			fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
596 			fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
597 			GrColorP1 = m_Doc->itemToolPrefs().shapeFillColor;
598 			GrColorP2 = m_Doc->itemToolPrefs().shapeFillColor;
599 			GrColorP3 = m_Doc->itemToolPrefs().shapeFillColor;
600 			GrColorP4 = m_Doc->itemToolPrefs().shapeFillColor;
601 		}
602 		else
603 		{
604 			if (m_lineColor != CommonStrings::None)
605 			{
606 				const ScColor& col = m_Doc->PageColors[m_lineColor];
607 				QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
608 				fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_lineColor, 100);
609 				fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_lineColor, 100);
610 				GrColorP1 = m_lineColor;
611 				GrColorP2 = m_lineColor;
612 				GrColorP3 = m_lineColor;
613 				GrColorP4 = m_lineColor;
614 			}
615 			else
616 			{
617 				if (m_Doc->itemToolPrefs().shapeLineColor != CommonStrings::None)
618 				{
619 					const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeLineColor];
620 					QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
621 					fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
622 					fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
623 					GrColorP1 = m_Doc->itemToolPrefs().shapeLineColor;
624 					GrColorP2 = m_Doc->itemToolPrefs().shapeLineColor;
625 					GrColorP3 = m_Doc->itemToolPrefs().shapeLineColor;
626 					GrColorP4 = m_Doc->itemToolPrefs().shapeLineColor;
627 				}
628 				else if (m_Doc->PageColors.contains("Black"))
629 				{
630 					const ScColor& col = m_Doc->PageColors["Black"];
631 					QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
632 					fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
633 					fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
634 					GrColorP1 = "Black";
635 					GrColorP2 = "Black";
636 					GrColorP3 = "Black";
637 					GrColorP4 = "Black";
638 				}
639 			}
640 		}
641 	}
642 	GrMaskEndX = w;
643 	mask_gradient = VGradient(VGradient::linear);
644 	mask_gradient.clearStops();
645 	const ScColor& col = m_Doc->PageColors["Black"];
646 	QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
647 	mask_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
648 	mask_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
649 
650 	QList<MeshPoint> mgList;
651 	MeshPoint mgP;
652 	meshGradientPatch patch;
653 	mgP.resetTo(FPoint(0.0, 0.0));
654 	mgP.transparency = 1.0;
655 	mgP.shade = 100;
656 	mgP.colorName = "Black";
657 	mgP.color = qcol;
658 	mgList.append(mgP);
659 	patch.TL = mgP;
660 	mgP.resetTo(FPoint(m_width / 2.0, 0.0));
661 	mgList.append(mgP);
662 	mgP.resetTo(FPoint(m_width, 0.0));
663 	mgList.append(mgP);
664 	patch.TR = mgP;
665 	meshGradientArray.append(mgList);
666 	mgList.clear();
667 	mgP.resetTo(FPoint(0.0, m_height / 2.0));
668 	mgList.append(mgP);
669 	mgP.resetTo(FPoint(m_width / 2.0, m_height / 2.0));
670 	mgList.append(mgP);
671 	mgP.resetTo(FPoint(m_width, m_height / 2.0));
672 	mgList.append(mgP);
673 	meshGradientArray.append(mgList);
674 	mgList.clear();
675 	mgP.resetTo(FPoint(0.0, m_height));
676 	mgList.append(mgP);
677 	patch.BL = mgP;
678 	mgP.resetTo(FPoint(m_width / 2.0, m_height));
679 	mgList.append(mgP);
680 	mgP.resetTo(FPoint(m_width, m_height));
681 	mgList.append(mgP);
682 	patch.BR = mgP;
683 	meshGradientArray.append(mgList);
684 	meshGradientPatches.append(patch);
685 
686 	m_firstLineOffset = m_Doc->itemToolPrefs().firstLineOffset;
687 	m_columns = m_Doc->itemToolPrefs().textColumns;
688 	m_columnGap = m_Doc->itemToolPrefs().textColumnGap;
689 
690 	OnMasterPage = m_Doc->currentPage() ? m_Doc->currentPage()->pageName() : QString();
691 	m_startArrowIndex = m_Doc->itemToolPrefs().lineStartArrow;
692 	m_endArrowIndex = m_Doc->itemToolPrefs().lineEndArrow;
693 	effectsInUse.clear();
694 
695 	//Page Item Attributes
696 	pageItemAttributes.clear();
697 	for (const ObjectAttribute& objAttr : qAsConst(m_Doc->itemAttributes()))
698 	{
699 		if ((objAttr.autoaddto == "textframes" && m_itemType == TextFrame) ||
700 			(objAttr.autoaddto == "imageframes" && m_itemType == ImageFrame))
701 		{
702 			pageItemAttributes.append(objAttr);
703 		}
704 	}
705 
706 	hatchBackground = CommonStrings::None;
707 	hatchBackgroundQ = QColor();
708 	hatchForeground = "Black";
709 	hatchForegroundQ = qcol;
710 }
711 
~PageItem()712 PageItem::~PageItem()
713 {
714 	if ((isTempFile) && (!Pfile.isEmpty()))
715 		QFile::remove(Pfile);
716 	//remove marks
717 
718 	if (isTextFrame())
719 	{
720 		if (!asTextFrame()->isInChain() && itemText.length() > 0)
721 		{
722 			for (int pos = 0; pos < itemText.length(); ++pos)
723 			{
724 				if (itemText.hasMark(pos))
725 				{
726 					Mark* mrk = itemText.mark(pos);
727 					if (!mrk->isType(MARKBullNumType))
728 						m_Doc->eraseMark(mrk);
729 				}
730 			}
731 		}
732 	}
733 //		if (isWeld())
734 //			unWeldFromMaster(true);
735 //		if (isWelded())
736 //			unWeldChild();
737 }
738 
isMasterItem() const739 bool PageItem::isMasterItem() const
740 {
741 	if (Parent == nullptr)
742 		return !OnMasterPage.isEmpty();
743 
744 	PageItem* parentItem = Parent;
745 	while (parentItem && parentItem->Parent)
746 		parentItem = parentItem->Parent;
747 	return !parentItem->OnMasterPage.isEmpty();
748 }
749 
isGroupChild() const750 bool PageItem::isGroupChild() const
751 {
752 	return (dynamic_cast<PageItem_Group*>(Parent) != nullptr);
753 }
754 
isTableCell() const755 bool PageItem::isTableCell() const
756 {
757 	return (dynamic_cast<PageItem_Table*>(Parent) != nullptr);
758 }
759 
setXPos(const double newXPos,bool drawingOnly)760 void PageItem::setXPos(const double newXPos, bool drawingOnly)
761 {
762 	m_xPos = newXPos;
763 	if (drawingOnly || m_Doc->isLoading())
764 		return;
765 	checkChanges();
766 }
767 
setYPos(const double newYPos,bool drawingOnly)768 void PageItem::setYPos(const double newYPos, bool drawingOnly)
769 {
770 	m_yPos = newYPos;
771 	if (drawingOnly || m_Doc->isLoading())
772 		return;
773 	checkChanges();
774 }
775 
setXYPos(const double newXPos,const double newYPos,bool drawingOnly)776 void PageItem::setXYPos(const double newXPos, const double newYPos, bool drawingOnly)
777 {
778 	m_xPos = newXPos;
779 	m_yPos = newYPos;
780 	if (drawingOnly || m_Doc->isLoading())
781 		return;
782 	checkChanges();
783 }
784 
level() const785 int PageItem::level() const
786 {
787 	PageItem* thisItem = const_cast<PageItem*>(this);
788 	if (isGroupChild())
789 		return (Parent->asGroupFrame()->groupItemList.indexOf(thisItem) + 1);
790 	if (!m_Doc)
791 		return 0;
792 	QList<PageItem*>* items = OnMasterPage.isEmpty() ? &m_Doc->DocItems : &m_Doc->MasterItems;
793 	return (items->indexOf(thisItem) + 1);
794 }
795 
moveBy(const double dX,const double dY,bool drawingOnly)796 void PageItem::moveBy(const double dX, const double dY, bool drawingOnly)
797 {
798 	//qDebug() << "pageitem::moveby" << dX << dY;
799 	if (dX==0.0 && dY==0.0)
800 		return;
801 	invalid = true;
802 	if (dX != 0.0)
803 	{
804 		m_xPos += dX;
805 		gXpos += dX;
806 		BoundingX += dX;
807 	}
808 	if (dY != 0.0)
809 	{
810 		m_yPos += dY;
811 		gYpos += dY;
812 		BoundingY += dY;
813 	}
814 	if (drawingOnly || m_Doc->isLoading())
815 		return;
816 	moveWelded(dX, dY);
817 	checkChanges();
818 }
819 
setWidth(double newWidth)820 void PageItem::setWidth(double newWidth)
821 {
822 	m_width = newWidth;
823 	updateConstants();
824 	if (m_Doc->isLoading())
825 		return;
826 	checkChanges();
827 }
828 
setHeight(double newHeight)829 void PageItem::setHeight(double newHeight)
830 {
831 	m_height = newHeight;
832 	updateConstants();
833 	if (m_Doc->isLoading())
834 		return;
835 	checkChanges();
836 }
837 
setWidthHeight(double newWidth,double newHeight,bool drawingOnly)838 void PageItem::setWidthHeight(double newWidth, double newHeight, bool drawingOnly)
839 {
840 	m_width = newWidth;
841 	m_height = newHeight;
842 	updateConstants();
843 	if (drawingOnly)
844 		return;
845 	checkChanges();
846 }
847 
setWidthHeight(const double newWidth,const double newHeight)848 void PageItem::setWidthHeight(const double newWidth, const double newHeight)
849 {
850 	m_width = newWidth;
851 	m_height = newHeight;
852 	updateConstants();
853 	if (m_Doc->isLoading())
854 		return;
855 	checkChanges();
856 }
857 
resizeBy(const double dH,const double dW)858 void PageItem::resizeBy(const double dH, const double dW)
859 {
860 	if (dH == 0.0 && dW == 0.0)
861 		return;
862 	if (dH != 0.0)
863 		m_width += dH;
864 	if (dW != 0.0)
865 		m_height += dW;
866 	updateConstants();
867 	if (m_Doc->isLoading())
868 		return;
869 	checkChanges();
870 }
871 
setRotation(const double newRotation,bool drawingOnly)872 void PageItem::setRotation(const double newRotation, bool drawingOnly)
873 {
874 	double dR = newRotation - m_rotation;
875 	double oldRot = m_rotation;
876 	m_rotation = newRotation;
877 	while (m_rotation < 0.0)
878 		m_rotation += 360.0;
879 	while (m_rotation > 360.0)
880 		m_rotation -= 360.0;
881 	if (drawingOnly || m_Doc->isLoading())
882 		return;
883 	rotateWelded(dR, oldRot);
884 	checkChanges();
885 }
886 
rotateBy(const double dR)887 void PageItem::rotateBy(const double dR)
888 {
889 	if (dR==0.0)
890 		return;
891 	m_rotation += dR;
892 	while (m_rotation < 0.0)
893 		m_rotation += 360.0;
894 	while (m_rotation > 360.0)
895 		m_rotation -= 360.0;
896 	if (m_Doc->isLoading())
897 		return;
898 	checkChanges();
899 }
900 
setSelected(const bool toSelect)901 void PageItem::setSelected(const bool toSelect)
902 {
903 	m_isSelected=toSelect;
904 }
905 
setImageXScale(const double newImageXScale)906 void PageItem::setImageXScale(const double newImageXScale)
907 {
908 	m_imageXScale = newImageXScale;
909 	if (m_Doc->isLoading())
910 	{
911 		oldLocalScX = m_imageXScale;
912 		return;
913 	}
914 	checkChanges();
915 }
916 
setImageYScale(const double newImageYScale)917 void PageItem::setImageYScale(const double newImageYScale)
918 {
919 	m_imageYScale = newImageYScale;
920 	if (m_Doc->isLoading())
921 	{
922 		oldLocalScY = m_imageYScale;
923 		return;
924 	}
925 	checkChanges();
926 }
927 
setImageXYScale(const double newImageXScale,const double newImageYScale)928 void PageItem::setImageXYScale(const double newImageXScale, const double newImageYScale)
929 {
930 	m_imageXScale = newImageXScale;
931 	m_imageYScale = newImageYScale;
932 	if (m_Doc->isLoading())
933 	{
934 		oldLocalScX = m_imageXScale;
935 		oldLocalScY = m_imageYScale;
936 		return;
937 	}
938 	checkChanges();
939 }
940 
setImageXOffset(const double newImageXOffset)941 void PageItem::setImageXOffset(const double newImageXOffset)
942 {
943 	m_imageXOffset = newImageXOffset;
944 	if (m_Doc->isLoading())
945 	{
946 		oldLocalX = m_imageXOffset;
947 		return;
948 	}
949 	checkChanges();
950 }
951 
setImageYOffset(const double newImageYOffset)952 void PageItem::setImageYOffset(const double newImageYOffset)
953 {
954 	m_imageYOffset = newImageYOffset;
955 	if (m_Doc->isLoading())
956 	{
957 		oldLocalY = m_imageYOffset;
958 		return;
959 	}
960 	checkChanges();
961 }
962 
setImageXYOffset(const double newImageXOffset,const double newImageYOffset)963 void PageItem::setImageXYOffset(const double newImageXOffset, const double newImageYOffset)
964 {
965 	m_imageXOffset = newImageXOffset;
966 	m_imageYOffset = newImageYOffset;
967 	if (m_Doc->isLoading())
968 	{
969 		oldLocalX = m_imageXOffset;
970 		oldLocalY = m_imageYOffset;
971 		return;
972 	}
973 	checkChanges();
974 }
975 
moveImageXYOffsetBy(const double dX,const double dY)976 void PageItem::moveImageXYOffsetBy(const double dX, const double dY)
977 {
978 	if (dX==0.0 && dY==0.0)
979 		return;
980 	if (dX != 0.0)
981 		m_imageXOffset += dX;
982 	if (dY != 0.0)
983 		m_imageYOffset += dY;
984 	if (m_Doc->isLoading())
985 		return;
986 	checkChanges();
987 }
988 
setImageRotation(const double newRotation)989 void PageItem::setImageRotation(const double newRotation)
990 {
991 	if (m_imageRotation == newRotation)
992 		return;
993 	if (UndoManager::undoEnabled())
994 	{
995 		SimpleState *ss = new SimpleState(Um::Rotate, QString(), Um::IRotate);
996 		ss->set("IMAGE_ROTATION");
997 		ss->set("OLD_ROT", m_imageRotation);
998 		ss->set("NEW_ROT", newRotation);
999 		undoManager->action(this, ss);
1000 	}
1001 	m_imageRotation = newRotation;
1002 	if (m_Doc->isLoading())
1003 		return;
1004 	checkChanges();
1005 }
1006 
1007 
1008 /// tests if a character is displayed by this frame
frameDisplays(int textpos) const1009 bool PageItem::frameDisplays(int textpos) const
1010 {
1011 	return 0 <= textpos && textpos < signed(m_maxChars) && textpos < itemText.length();
1012 }
1013 
frameOfChar(int textPos)1014 PageItem* PageItem::frameOfChar(int textPos)
1015 {
1016 	PageItem* firstFrame = this->firstInChain();
1017 	PageItem* nextFrame = firstFrame;
1018 
1019 	while (nextFrame)
1020 	{
1021 		if (nextFrame->invalid)
1022 			nextFrame->layout();
1023 		if (nextFrame->frameDisplays(textPos))
1024 			return nextFrame;
1025 		nextFrame = nextFrame->nextInChain();
1026 	}
1027 
1028 	return nullptr;
1029 }
1030 
1031 //return frame where is text end
frameTextEnd()1032 PageItem * PageItem::frameTextEnd()
1033 {
1034 	PageItem * LastBox = this;
1035 	if (frameOverflows() && m_nextBox)
1036 	{ // text ending in some next frame
1037 		LastBox = m_nextBox;
1038 		while (LastBox != nullptr && !LastBox->frameDisplays(itemText.length()-1))
1039 			LastBox = LastBox->nextInChain();
1040 	}
1041 	else if (frameUnderflows() && m_backBox)
1042 	{ //text ending in some previous frame
1043 		LastBox = m_backBox;
1044 		while (LastBox != nullptr && !LastBox->frameDisplays(itemText.length()-1))
1045 			LastBox = LastBox->prevInChain();
1046 	}
1047 	return LastBox;
1048 }
1049 
1050 /// returns true if text overflows
frameOverflows() const1051 bool PageItem::frameOverflows() const
1052 {
1053 	// Fix #6991 : "Text overflow" warning when there is a text underflow in fact
1054 	/*return NextBox == nullptr && itemText.length() > static_cast<int>(MaxChars);*/
1055 	return ( m_nextBox == nullptr )
1056 		   && ( firstChar < itemText.length() )
1057 		   // Fix #7766 : scribus.textOverflows() returns 0 if there is no place for the overflow mark
1058 		   /*&& ( firstChar < MaxChars )*/
1059 		   && ( firstChar <= m_maxChars )
1060 		   && ( itemText.length() > m_maxChars );
1061 }
1062 
frameOverflowCount() const1063 int PageItem::frameOverflowCount() const
1064 {
1065 	if (frameOverflows())
1066 		return itemText.length()-m_maxChars;
1067 	return 0;
1068 }
1069 
frameOverflowBlankCount() const1070 int PageItem::frameOverflowBlankCount() const
1071 {
1072 	if (frameOverflows())
1073 		return itemText.plainText().right(itemText.length() - m_maxChars).count(QRegularExpression("\\s+"));
1074 	return 0;
1075 }
1076 
maxCharsInFrame()1077 int PageItem::maxCharsInFrame()
1078 {
1079 	return m_maxChars;
1080 }
1081 
1082 /// returns true if text is ending before that frame
frameUnderflows() const1083 bool PageItem::frameUnderflows() const
1084 {
1085 	if (m_backBox == nullptr)
1086 		return false;
1087 	//FIX ME - I have found that condition if frame is empty
1088 	//and has been linked with previous frame
1089 	//if you will find any better solution - fix that function
1090 	return (firstInFrame() > lastInFrame());
1091 }
1092 
drawOverflowMarker(ScPainter * p)1093 void PageItem::drawOverflowMarker(ScPainter *p)
1094 {
1095 	qreal sideLength = 10 / qMax(p->zoomFactor(), 1.0);
1096 	qreal offset = 1 / qMax(p->zoomFactor(), 1.0);
1097 	qreal left = m_width - sideLength-offset;// / 2;
1098 	qreal right = left + sideLength;
1099 	qreal top = m_height - sideLength-offset;// * 1.5;
1100 	qreal bottom = top + sideLength;
1101 
1102 	QColor color(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor);
1103 	if ((isBookmark) || (m_isAnnotation))
1104 		color = PrefsManager::instance().appPrefs.displayPrefs.frameAnnotationColor;
1105 	if ((m_backBox != nullptr) || (m_nextBox != nullptr))
1106 		color = PrefsManager::instance().appPrefs.displayPrefs.frameLinkColor;
1107 	if (m_Locked)
1108 		color = PrefsManager::instance().appPrefs.displayPrefs.frameLockColor;
1109 	if (m_Doc->m_Selection->containsItem(this))
1110 		color = Qt::red;
1111 
1112 	p->save();
1113 
1114 	p->setPen(color, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1115 	p->setPenOpacity(1.0);
1116 	p->setBrush(Qt::white);
1117 	p->setBrushOpacity(1.0);
1118 	p->setFillMode(ScPainter::Solid);
1119 	p->drawSharpRect(left, top, sideLength, sideLength);
1120 	p->drawSharpLine(QPointF(left, top), QPointF(right, bottom));
1121 	p->drawSharpLine(QPointF(left, bottom), QPointF(right, top));
1122 
1123 	p->restore();
1124 }
1125 
firstInFrame() const1126 int PageItem::firstInFrame() const
1127 {
1128 	return firstChar;
1129 }
1130 
lastInFrame() const1131 int PageItem::lastInFrame() const
1132 {
1133 	return qMin(signed(m_maxChars), itemText.length()) - 1;
1134 }
1135 
canBeLinkedTo(const PageItem * nxt) const1136 bool PageItem::canBeLinkedTo(const PageItem* nxt) const
1137 {
1138 	if (this->nextInChain() )
1139 		return false;
1140 	if (!nxt || nxt->prevInChain() )
1141 		return false;
1142 	for (const PageItem* ff = nxt; ff; ff = ff->nextInChain())
1143 	{
1144 		if (ff == this)
1145 			return false;
1146 	}
1147 	// If object is placed on a master page, it can be linked only to objects placed on same master page
1148 	// Same for objects placed on standard pages : they can only be linked to objects placed on standard pages
1149 	return OnMasterPage == nxt->OnMasterPage;
1150 }
1151 
link(PageItem * nxt,bool addPARSEP)1152 void PageItem::link(PageItem* nxt, bool addPARSEP)
1153 {
1154 	assert( !nextInChain() );
1155 	assert( !nxt->prevInChain() );
1156 	for (PageItem* ff=nxt; ff; ff=ff->nextInChain())
1157 	{
1158 		assert (ff != this);
1159 	}
1160 	// Append only if necessary to avoid the
1161 	// charstyle: access at end of text warning
1162 	bool first = false;
1163 	bool createUndo = addPARSEP;
1164 
1165 	if (nxt->prevInChain() == nullptr)
1166 		first = true;
1167 	int textLen = itemText.length();
1168 	if (nxt->itemText.length() > 0)
1169 	{   //case when text will be joined with next frame text
1170 		//do not add PARSEP if first frame has no text or text ends already with PARSEP
1171 		if (addPARSEP && (textLen > 0) && (itemText.text(textLen-1) != SpecialChars::PARSEP))
1172 			itemText.insertChars(textLen, SpecialChars::PARSEP);
1173 		else
1174 			addPARSEP = false;
1175 		itemText.append(nxt->itemText);
1176 	}
1177 	else
1178 		addPARSEP = false;
1179 	m_nextBox = nxt;
1180 	nxt->m_backBox = this;
1181 	// update AutoText
1182 	if (isAutoText)
1183 	{
1184 		PageItem* after = nxt;
1185 		while (after)
1186 		{
1187 			after->isAutoText = true;
1188 			m_Doc->LastAuto = after;
1189 			after = after->m_nextBox;
1190 		}
1191 	}
1192 	else if (nxt->isAutoText)
1193 	{
1194 		PageItem* before = this;
1195 		while (before)
1196 		{
1197 			before->isAutoText = true;
1198 			m_Doc->FirstAuto = before;
1199 			before = before->m_backBox;
1200 		}
1201 	}
1202 	invalid = true;
1203 	PageItem* prev = this;
1204 	while (prev->m_backBox && !prev->m_backBox->frameOverflows())
1205 	{
1206 		prev->m_backBox->invalid = true;
1207 		prev = prev->m_backBox;
1208 	}
1209 	while (nxt)
1210 	{
1211 		nxt->itemText = itemText;
1212 		nxt->invalid = true;
1213 		nxt->firstChar = 0;
1214 		nxt = nxt->m_nextBox;
1215 	}
1216 	if (UndoManager::undoEnabled() && createUndo) //addPARESEP is false only if linking is invoked from undo action for unlinkWithText
1217 	{
1218 		ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::LinkTextFrame);
1219 		is->set("LINK_TEXT_FRAME");
1220 		is->set("FIRST", first);
1221 		is->set("JOIN_POS", textLen);
1222 		is->set("ADDPARSEP", addPARSEP);
1223 		is->setItem(qMakePair(this, m_nextBox));
1224 		undoManager->action(this, is);
1225 	}
1226 }
1227 
unlink(bool createUndo)1228 void PageItem::unlink(bool createUndo)
1229 {
1230 	if (m_nextBox)
1231 	{
1232 		PageItem *undoNextBox=m_nextBox;
1233 		// make sure lastInFrame is valid
1234 		layout();
1235 		/*
1236 		//<< CB #6332: Stop the StoryText cut and break and act like other publishing apps
1237 		// move following text to new StoryText
1238 		itemText.select(lastInFrame()+1, itemText.length()-lastInFrame()-1);
1239 		*/
1240 		StoryText follow(m_Doc);
1241 		/*
1242 		follow.setDefaultStyle(itemText.defaultStyle());
1243 		follow.insert(0, itemText, true);
1244 		// remove following text from this chain
1245 		itemText.removeSelection();
1246 		//>>
1247 		*/
1248 		// update auto pointers
1249 		if (isAutoText)
1250 		{
1251 			PageItem* before = this;
1252 			while (before)
1253 			{
1254 				before->isAutoText = false;
1255 				before = before->m_backBox;
1256 			}
1257 			m_Doc->FirstAuto = m_nextBox;
1258 		}
1259 		// link following frames to new text
1260 		m_nextBox->firstChar = 0;
1261 		m_nextBox->m_backBox = nullptr;
1262 		while (m_nextBox)
1263 		{
1264 			m_nextBox->itemText = follow;
1265 			m_nextBox->invalid = true;
1266 			m_nextBox->firstChar = 0;
1267 			m_nextBox = m_nextBox->m_nextBox;
1268 		}
1269 		// NextBox == nullptr now
1270 		m_nextBox = nullptr;
1271 		if (UndoManager::undoEnabled() && createUndo)
1272 		{
1273 			ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
1274 			is->set("UNLINK_TEXT_FRAME");
1275 			is->setItem(qMakePair(this, undoNextBox));
1276 			undoManager->action(this, is);
1277 		}
1278 	}
1279 }
1280 
dropLinks()1281 void PageItem::dropLinks()
1282 {
1283 	// update auto pointers
1284 	if (isAutoText && m_nextBox == nullptr)
1285 		m_Doc->LastAuto = m_backBox;
1286 	if (isAutoText && m_backBox == nullptr)
1287 		m_Doc->FirstAuto = m_nextBox;
1288 	isAutoText = false;
1289 
1290 	// leave text in remaining chain
1291 	PageItem* before = m_backBox;
1292 	PageItem* after = m_nextBox;
1293 	if (after == nullptr && before == nullptr)
1294 		return;
1295 
1296 	itemText = StoryText(m_Doc);
1297 
1298 	int afterChar = 0;
1299 	if (before)
1300 	{
1301 		before->m_nextBox = after;
1302 		afterChar = qMin((int) before->m_maxChars, before->itemText.length());
1303 	}
1304 	if (after)
1305 	{
1306 		after->m_backBox = before;
1307 		while (after)
1308 		{
1309 			after->invalid = true;
1310 			after->firstChar = afterChar;
1311 			after = after->m_nextBox;
1312 		}
1313 	}
1314 
1315 	if (UndoManager::undoEnabled())
1316 	{
1317 		ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
1318 		is->set("DROP_LINKS");
1319 		is->setItem(qMakePair(m_backBox, m_nextBox));
1320 		undoManager->action(this, is);
1321 	}
1322 
1323 	// JG we should set BackBox and NextBox to nullptr at a point
1324 	m_backBox = m_nextBox = nullptr;
1325 }
1326 
1327 //unlink selected frame from text chain
1328 //but copy or cut its content from itemText
unlinkWithText()1329 void PageItem::unlinkWithText()
1330 {
1331 	PageItem* next = m_nextBox;
1332 	PageItem* prev = m_backBox;
1333 	int length = itemText.length();
1334 
1335 	if (this->invalid)
1336 		layout();
1337 
1338 	//unlink first frame in chain
1339 	if (prev == nullptr)
1340 	{
1341 		if (next->invalid)
1342 			next->layout();
1343 		if (lastInFrame() < length -1)
1344 		{
1345 			StoryText content(m_Doc);
1346 			itemText.select(lastInFrame() + 1, length - (lastInFrame() + 1));
1347 			content.insert(0, itemText, true);
1348 			itemText.removeSelection();
1349 			unlink(false);
1350 			next->itemText.insert(0, content);
1351 			next->update();
1352 		}
1353 		else
1354 		{
1355 			unlink(false);
1356 		}
1357 	}
1358 	else
1359 	{
1360 		if (prev->invalid)
1361 			prev->layout();
1362 		itemText.select(firstInFrame(), length - firstInFrame());
1363 		StoryText content(m_Doc);
1364 		content.insert(0, itemText, true);
1365 		itemText.removeSelection();
1366 		prev->unlink(false);
1367 		itemText.insert(0, content);
1368 		update();
1369 	}
1370 	if (UndoManager::undoEnabled())
1371 	{
1372 		ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
1373 		is->set("UNLINK_TEXT_FRAME");
1374 		is->set("CUT_TEXT", true);
1375 		is->setItem(qMakePair(prev, next));
1376 		undoManager->action(this, is);
1377 	}
1378 }
1379 
1380 /// returns the style at the current charpos
currentStyle() const1381 const ParagraphStyle& PageItem::currentStyle() const
1382 {
1383 	int cursorPosition = itemText.cursorPosition();
1384 	if (itemText.hasSelection())
1385 	{
1386 		int firstSelected = itemText.startOfSelection();
1387 		int lastSelected  = qMax(itemText.endOfSelection() - 1, 0);
1388 		cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
1389 	}
1390 	// Note: cursor position can be past last characters, don't use frameDisplays() here
1391 	if (cursorPosition >= 0 && cursorPosition <= itemText.length())
1392 		return itemText.paragraphStyle(cursorPosition);
1393 	return itemText.defaultStyle();
1394 }
1395 
1396 /// returns the style at the current charpos for changing
changeCurrentStyle()1397 ParagraphStyle& PageItem::changeCurrentStyle()
1398 {
1399 	int cursorPosition = itemText.cursorPosition();
1400 	if (itemText.hasSelection())
1401 	{
1402 		int firstSelected = itemText.startOfSelection();
1403 		int lastSelected  = qMax(itemText.endOfSelection() - 1, 0);
1404 		cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
1405 	}
1406 	// Note: cursor position can be past last characters, don't use frameDisplays() here
1407 	if (cursorPosition >= 0 && cursorPosition <= itemText.length())
1408 		return const_cast<ParagraphStyle&>(itemText.paragraphStyle(cursorPosition));
1409 	return const_cast<ParagraphStyle&>(itemText.defaultStyle());
1410 }
1411 
1412 /// returns the style at the current charpos
currentCharStyle() const1413 const CharStyle& PageItem::currentCharStyle() const
1414 {
1415 	int cursorPosition = itemText.cursorPosition();
1416 	if (itemText.hasSelection())
1417 	{
1418 		int firstSelected = itemText.startOfSelection();
1419 		int lastSelected  = qMax(itemText.endOfSelection() - 1, 0);
1420 		cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
1421 	}
1422 	// Note: cursor position can be past last characters, don't use frameDisplays() here
1423 	if (cursorPosition >= 0 && cursorPosition <= itemText.length())
1424 		return itemText.charStyle(cursorPosition);
1425 	return itemText.defaultStyle().charStyle();
1426 }
1427 
currentTextProps(ParagraphStyle & parStyle) const1428 void PageItem::currentTextProps(ParagraphStyle& parStyle) const
1429 {
1430 	const ParagraphStyle& curStyle = this->currentStyle();
1431 	parStyle.setContext(curStyle.context());
1432 	parStyle = curStyle;
1433 
1434 	int position = itemText.cursorPosition();
1435 	if (itemText.hasSelection())
1436 		position = qMin(qMax(itemText.endOfSelection() - 1, 0), qMax(position, itemText.startOfSelection()));
1437 
1438 	// Note: cursor position can be past last characters, don't use frameDisplays() here
1439 	if (position >= 0 && position <= itemText.length())
1440 	{
1441 		// Do not use setStyle here otherwise char style properties explicitly
1442 		// set at paragraph level without using styles might get lost
1443 		parStyle.charStyle().applyCharStyle( itemText.charStyle(position) );
1444 	}
1445 	else
1446 		parStyle.charStyle().setStyle( itemText.defaultStyle().charStyle() );
1447 }
1448 
setTextToFrameDistLeft(double newLeft)1449 void PageItem::setTextToFrameDistLeft(double newLeft)
1450 {
1451 	if (m_textDistanceMargins.left() == newLeft)
1452 		return;
1453 	if (UndoManager::undoEnabled())
1454 	{
1455 		SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
1456 		ss->set("LEFT_TEXTFRAMEDIST");
1457 		ss->set("OLD_DIST", m_textDistanceMargins.left());
1458 		ss->set("NEW_DIST", newLeft);
1459 		undoManager->action(this, ss);
1460 	}
1461 	m_textDistanceMargins.setLeft(newLeft);
1462 	//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
1463 }
1464 
setTextToFrameDistRight(double newRight)1465 void PageItem::setTextToFrameDistRight(double newRight)
1466 {
1467 	if (m_textDistanceMargins.right() == newRight)
1468 		return;
1469 	if (UndoManager::undoEnabled())
1470 	{
1471 		SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
1472 		ss->set("RIGHT_TEXTFRAMEDIST");
1473 		ss->set("OLD_DIST", m_textDistanceMargins.right());
1474 		ss->set("NEW_DIST", newRight);
1475 		undoManager->action(this, ss);
1476 	}
1477 	m_textDistanceMargins.setRight(newRight);
1478 	//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
1479 }
1480 
setTextToFrameDistTop(double newTop)1481 void PageItem::setTextToFrameDistTop(double newTop)
1482 {
1483 	if (m_textDistanceMargins.top() == newTop)
1484 		return;
1485 	if (UndoManager::undoEnabled())
1486 	{
1487 		SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
1488 		ss->set("TOP_TEXTFRAMEDIST");
1489 		ss->set("OLD_DIST", m_textDistanceMargins.top());
1490 		ss->set("NEW_DIST", newTop);
1491 		undoManager->action(this, ss);
1492 	}
1493 	m_textDistanceMargins.setTop(newTop);
1494 	//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
1495 }
1496 
setTextToFrameDistBottom(double newBottom)1497 void PageItem::setTextToFrameDistBottom(double newBottom)
1498 {
1499 	if (m_textDistanceMargins.bottom() == newBottom)
1500 		return;
1501 	if (UndoManager::undoEnabled())
1502 	{
1503 		SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
1504 		ss->set("BOTTOM_TEXTFRAMEDIST");
1505 		ss->set("OLD_DIST", m_textDistanceMargins.bottom());
1506 		ss->set("NEW_DIST", newBottom);
1507 		undoManager->action(this, ss);
1508 	}
1509 	m_textDistanceMargins.setBottom(newBottom);
1510 	//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
1511 }
1512 
setTextToFrameDist(double newLeft,double newRight,double newTop,double newBottom)1513 void PageItem::setTextToFrameDist(double newLeft, double newRight, double newTop, double newBottom)
1514 {
1515 	UndoTransaction activeTransaction;
1516 	if (UndoManager::undoEnabled())
1517 		activeTransaction = undoManager->beginTransaction(Um::TextFrame, Um::IDocument, Um::TextFrameDist, QString(), Um::ITextFrame);
1518 	setTextToFrameDistLeft(newLeft);
1519 	setTextToFrameDistRight(newRight);
1520 	setTextToFrameDistTop(newTop);
1521 	setTextToFrameDistBottom(newBottom);
1522 	if (activeTransaction)
1523 		activeTransaction.commit();
1524 	//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
1525 }
1526 
gridOffset() const1527 double PageItem::gridOffset() const
1528 {
1529 	return m_Doc->guidesPrefs().offsetBaselineGrid;
1530 }
gridDistance() const1531 double PageItem::gridDistance() const
1532 {
1533 	return m_Doc->guidesPrefs().valueBaselineGrid;
1534 }
1535 
setGridOffset(double)1536 void PageItem::setGridOffset(double) { } // FIXME
setGridDistance(double)1537 void PageItem::setGridDistance(double) { } // FIXME
1538 
setColumns(int newColumnCount)1539 void PageItem::setColumns(int newColumnCount)
1540 {
1541 	if (m_columns==newColumnCount)
1542 		return;
1543 	if (UndoManager::undoEnabled())
1544 	{
1545 		SimpleState *ss = new SimpleState(Um::Columns, QString(), Um::IBorder);
1546 		ss->set("COLUMNS");
1547 		ss->set("OLD_COLUMNS", m_columns);
1548 		ss->set("NEW_COLUMNS", newColumnCount);
1549 		undoManager->action(this, ss);
1550 	}
1551 	m_columns = qMax(1, newColumnCount);
1552 }
1553 
setColumnGap(double newColumnGap)1554 void PageItem::setColumnGap(double newColumnGap)
1555 {
1556 	if (m_columnGap==newColumnGap)
1557 		return;
1558 	if (UndoManager::undoEnabled())
1559 	{
1560 		SimpleState *ss = new SimpleState(Um::Columns, QString(), Um::IBorder);
1561 		ss->set("COLUMNSGAP");
1562 		ss->set("OLD_COLUMNS", m_columnGap);
1563 		ss->set("NEW_COLUMNS", newColumnGap);
1564 		undoManager->action(this, ss);
1565 	}
1566 	m_columnGap = newColumnGap;
1567 }
1568 
verticalAlignment()1569 int PageItem::verticalAlignment()
1570 {
1571 	return verticalAlign;
1572 }
1573 
setVerticalAlignment(int val)1574 void PageItem::setVerticalAlignment(int val)
1575 {
1576 	if (val == verticalAlign)
1577 		return;
1578 	if (UndoManager::undoEnabled())
1579 	{
1580 		SimpleState *ss = new SimpleState(Um::AlignText, QString(), Um::ITextFrame);
1581 		ss->set("VERTICAL_ALIGN");
1582 		ss->set("OLD_VERTALIGN", verticalAlign);
1583 		ss->set("NEW_VERTALIGN", val);
1584 		undoManager->action(this, ss);
1585 	}
1586 	verticalAlign = val;
1587 }
1588 
setCornerRadius(double newRadius)1589 void PageItem::setCornerRadius(double newRadius)
1590 {
1591 	if (m_roundedCornerRadius == newRadius)
1592 		return;
1593 	if (UndoManager::undoEnabled())
1594 	{
1595 		SimpleState *state = new SimpleState(Um::RoundCorner, QString(), Um::IBorder);
1596 		state->set("CORNER_RADIUS");
1597 		state->set("OLD_RADIUS", m_roundedCornerRadius);
1598 		state->set("NEW_RADIUS", newRadius);
1599 		undoManager->action(this,state);
1600 	}
1601 	m_roundedCornerRadius=newRadius;
1602 	//emit cornerRadius(RadRect);
1603 }
1604 
1605 
1606 
1607 /** Paints the item.
1608     CHANGE: cullingArea is in doc coordinates!
1609  */
DrawObj(ScPainter * p,QRectF cullingArea)1610 void PageItem::DrawObj(ScPainter *p, QRectF cullingArea)
1611 {
1612 	// #12698: Prevent drawing of line items
1613 	/*if (PoLine.isEmpty())
1614 		return;*/
1615 	if (cullingArea.isNull())
1616 	{
1617 		cullingArea = QRectF(QPointF(m_Doc->minCanvasCoordinate.x(), m_Doc->minCanvasCoordinate.y()),
1618 							 QPointF(m_Doc->maxCanvasCoordinate.x(), m_Doc->maxCanvasCoordinate.y())).toAlignedRect();
1619 	}
1620 
1621 	no_fill = false;
1622 	no_stroke = false;
1623 	DrawObj_Pre(p);
1624 	if (m_Doc->layerOutline(m_layerID))
1625 	{
1626 		if ((itemType() == TextFrame || itemType() == ImageFrame || itemType() == PathText || itemType() == Line || itemType() == PolyLine || itemType() == Group || itemType() == Symbol))
1627 			DrawObj_Item(p, cullingArea);
1628 	}
1629 	else
1630 	{
1631 		DrawObj_Item(p, cullingArea);
1632 	}
1633 	DrawObj_Post(p);
1634 }
1635 
DrawObj_Pre(ScPainter * p)1636 void PageItem::DrawObj_Pre(ScPainter *p)
1637 {
1638 	p->save();
1639 	double lwCorr = m_lineWidth;
1640 	double sc = p->zoomFactor();
1641 	if ((m_lineWidth * sc) < 1)
1642 		lwCorr = 0;
1643 	if (!isEmbedded)
1644 		p->translate(m_xPos, m_yPos);
1645 	p->rotate(m_rotation);
1646 
1647 	if (m_Doc->layerOutline(m_layerID))
1648 	{
1649 		p->setPen(m_Doc->layerMarker(m_layerID), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1650 		p->setFillMode(ScPainter::None);
1651 		p->setBrushOpacity(1.0);
1652 		p->setPenOpacity(1.0);
1653 		return;
1654 	}
1655 
1656 	if ((hasSoftShadow()) && (m_Doc->appMode != modeEdit))
1657 		DrawSoftShadow(p);
1658 	if (isGroup())
1659 		return;
1660 	p->setBlendModeFill(fillBlendmode());
1661 	p->setLineWidth(lwCorr);
1662 	if (GrType != 0)
1663 	{
1664 		if (GrType == Gradient_Pattern)
1665 		{
1666 			ScPattern *pattern = m_Doc->checkedPattern(m_patternName);
1667 			if (!pattern)
1668 			{
1669 				p->fill_gradient = VGradient(VGradient::linear);
1670 				p->fill_gradient.setRepeatMethod(GrExtend);
1671 				if (fillColor() != CommonStrings::None)
1672 				{
1673 					p->setBrush(m_fillQColor);
1674 					p->setFillMode(ScPainter::Solid);
1675 				}
1676 				else
1677 				{
1678 					no_fill = true;
1679 					p->setFillMode(ScPainter::None);
1680 				}
1681 				if ((!m_patternName.isEmpty()) && (!m_Doc->docPatterns.contains(m_patternName)))
1682 				{
1683 					GrType = 0;
1684 					m_patternName = "";
1685 				}
1686 			}
1687 			else
1688 			{
1689 				p->setPattern(pattern, patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternMirrorX, patternMirrorY);
1690 				p->setFillMode(ScPainter::Pattern);
1691 			}
1692 		}
1693 		else
1694 		{
1695 			if (GrType == Gradient_4Colors)
1696 			{
1697 				p->setFillMode(ScPainter::Gradient);
1698 				FPoint pG1 = FPoint(0, 0);
1699 				FPoint pG2 = FPoint(width(), 0);
1700 				FPoint pG3 = FPoint(width(), height());
1701 				FPoint pG4 = FPoint(0, height());
1702 				p->set4ColorGeometry(pG1, pG2, pG3, pG4, GrControl1, GrControl2, GrControl3, GrControl4);
1703 				p->set4ColorColors(m_grQColorP1, m_grQColorP2, m_grQColorP3, m_grQColorP4);
1704 			}
1705 			else if (GrType == Gradient_Hatch)
1706 			{
1707 				if (fillColor() != CommonStrings::None)
1708 					p->setBrush(m_fillQColor);
1709 				p->setFillMode(ScPainter::Hatch);
1710 				p->setHatchParameters(hatchType, hatchDistance, hatchAngle, hatchUseBackground, hatchBackgroundQ, hatchForegroundQ, width(), height());
1711 			}
1712 			else
1713 			{
1714 				if ((!m_gradientName.isEmpty()) && (!m_Doc->docGradients.contains(m_gradientName)))
1715 					m_gradientName = "";
1716 				if (!(m_gradientName.isEmpty()) && (m_Doc->docGradients.contains(m_gradientName)))
1717 					fill_gradient = m_Doc->docGradients[m_gradientName];
1718 				if ((fill_gradient.stops() < 2) && (GrType < Gradient_4Colors)) // fall back to solid filling if there are not enough colorstops in the gradient.
1719 				{
1720 					if (fillColor() != CommonStrings::None)
1721 					{
1722 						p->setBrush(m_fillQColor);
1723 						p->setFillMode(ScPainter::Solid);
1724 					}
1725 					else
1726 					{
1727 						no_fill = true;
1728 						p->setFillMode(ScPainter::None);
1729 					}
1730 				}
1731 				else
1732 				{
1733 					p->setFillMode(ScPainter::Gradient);
1734 					p->fill_gradient = fill_gradient;
1735 					p->fill_gradient.setRepeatMethod(GrExtend);
1736 					switch (GrType)
1737 					{
1738 						case Gradient_LinearLegacy1:
1739 						case Gradient_LinearLegacy2:
1740 						case Gradient_LinearLegacy3:
1741 						case Gradient_LinearLegacy4:
1742 						case Gradient_Linear:
1743 							p->setGradient(VGradient::linear, FPoint(GrStartX, GrStartY), FPoint(GrEndX, GrEndY), FPoint(GrStartX, GrStartY), GrScale, GrSkew);
1744 							break;
1745 						case Gradient_RadialLegacy5:
1746 						case Gradient_Radial:
1747 							p->setGradient(VGradient::radial, FPoint(GrStartX, GrStartY), FPoint(GrEndX, GrEndY), FPoint(GrFocalX, GrFocalY), GrScale, GrSkew);
1748 							break;
1749 						case Gradient_Diamond:
1750 							p->setFillMode(ScPainter::Gradient);
1751 							p->setDiamondGeometry(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), GrControl1, GrControl2, GrControl3, GrControl4, GrControl5);
1752 							break;
1753 						case Gradient_Mesh:
1754 						case Gradient_Conical:
1755 							p->setFillMode(ScPainter::Gradient);
1756 							p->setMeshGradient(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), meshGradientArray);
1757 							break;
1758 						case Gradient_PatchMesh:
1759 							p->setFillMode(ScPainter::Gradient);
1760 							p->setMeshGradient(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), meshGradientPatches);
1761 							break;
1762 					}
1763 				}
1764 			}
1765 		}
1766 	}
1767 	else
1768 	{
1769 		p->fill_gradient = VGradient(VGradient::linear);
1770 		if (fillColor() != CommonStrings::None)
1771 		{
1772 			p->setBrush(m_fillQColor);
1773 			p->setFillMode(ScPainter::Solid);
1774 		}
1775 		else
1776 		{
1777 			no_fill = true;
1778 			p->setFillMode(ScPainter::None);
1779 		}
1780 	}
1781 	if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0))
1782 	{
1783 		p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
1784 		if (DashValues.count() != 0)
1785 			p->setDash(DashValues, DashOffset);
1786 	}
1787 	else
1788 		p->setLineWidth(0);
1789 	p->setBrushOpacity(1.0 - fillTransparency());
1790 	p->setPenOpacity(1.0 - lineTransparency());
1791 	p->setFillRule(fillRule);
1792 	if ((GrMask == GradMask_Linear) || (GrMask == GradMask_Radial) || (GrMask == GradMask_LinearLumAlpha) || (GrMask == GradMask_RadialLumAlpha))
1793 	{
1794 		if ((GrMask == GradMask_Linear) || (GrMask == GradMask_Radial))
1795 			p->setMaskMode(1);
1796 		else
1797 			p->setMaskMode(3);
1798 		if ((!gradientMaskVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientMaskVal)))
1799 			gradientMaskVal = "";
1800 		if (!(gradientMaskVal.isEmpty()) && (m_Doc->docGradients.contains(gradientMaskVal)))
1801 			mask_gradient = m_Doc->docGradients[gradientMaskVal];
1802 		p->mask_gradient = mask_gradient;
1803 		if ((GrMask == GradMask_Linear) || (GrMask == GradMask_LinearLumAlpha))
1804 			p->setGradientMask(VGradient::linear, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskStartX, GrMaskStartY), GrMaskScale, GrMaskSkew);
1805 		else
1806 			p->setGradientMask(VGradient::radial, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskFocalX, GrMaskFocalY), GrMaskScale, GrMaskSkew);
1807 	}
1808 	else if ((GrMask == GradMask_Pattern) || (GrMask == GradMask_PatternLumAlpha) || (GrMask == GradMask_PatternLumAlphaInverted) || (GrMask == GradMask_PatternInverted))
1809 	{
1810 		ScPattern *patternMask = m_Doc->checkedPattern(patternMaskVal);
1811 		if (patternMask)
1812 		{
1813 			p->setPatternMask(patternMask, patternMaskScaleX, patternMaskScaleY, patternMaskOffsetX, patternMaskOffsetY, patternMaskRotation, patternMaskSkewX, patternMaskSkewY, patternMaskMirrorX, patternMaskMirrorY);
1814 			if (GrMask == GradMask_Pattern)
1815 				p->setMaskMode(2);
1816 			else if (GrMask == GradMask_PatternLumAlpha)
1817 				p->setMaskMode(4);
1818 			else if (GrMask == GradMask_PatternLumAlphaInverted)
1819 				p->setMaskMode(5);
1820 			else
1821 				p->setMaskMode(6);
1822 		}
1823 		else
1824 		{
1825 			p->setMaskMode(0);
1826 		}
1827 	}
1828 	else
1829 		p->setMaskMode(0);
1830 }
1831 
DrawObj_Post(ScPainter * p)1832 void PageItem::DrawObj_Post(ScPainter *p)
1833 {
1834 	bool doStroke=true;
1835 	double lwCorr = m_lineWidth;
1836 	if ((m_lineWidth * p->zoomFactor()) < 1)
1837 		lwCorr = 0;
1838 	if (m_Doc->layerOutline(m_layerID))
1839 	{
1840 		if (itemType()!=Line)
1841 		{
1842 			p->setPen(m_Doc->layerMarker(m_layerID), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1843 			p->setFillMode(ScPainter::None);
1844 			p->setBrushOpacity(1.0);
1845 			p->setPenOpacity(1.0);
1846 			if (itemType() == PolyLine)
1847 				p->setupPolygon(&PoLine, false);
1848 			else if (itemType() == PathText)
1849 			{
1850 				if (PoShow)
1851 					p->setupPolygon(&PoLine, false);
1852 				else
1853 					doStroke = false;
1854 			}
1855 			else
1856 				p->setupPolygon(&PoLine);
1857 			if (doStroke)
1858 				p->strokePath();
1859 			if (itemType() == ImageFrame)
1860 			{
1861 				if (!imageClip.empty())
1862 				{
1863 					p->setupPolygon(&imageClip);
1864 					p->strokePath();
1865 				}
1866 			}
1867 		}
1868 	}
1869 	else
1870 	{
1871 		if (!isGroup())
1872 		{
1873 			p->setBlendModeFill(0);
1874 			p->setMaskMode(0);
1875 			// TODO: Investigate whether itemType() == Table should really be here. I got artifacts without it so keeping it here for now. /estan
1876 			if (itemType() == PathText || itemType() == PolyLine || itemType() == Spiral || itemType() == Line || itemType() == Symbol || itemType() == Group || itemType() == Table)
1877 				doStroke=false;
1878 			if ((doStroke) && (!m_Doc->RePos))
1879 			{
1880 				p->setBlendModeStroke(lineBlendmode());
1881 				p->setPenOpacity(1.0 - lineTransparency());
1882 				if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0))
1883 				{
1884 					p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
1885 					if (DashValues.count() != 0)
1886 						p->setDash(DashValues, DashOffset);
1887 				}
1888 				else
1889 					p->setLineWidth(0);
1890 				if ((itemType() == LatexFrame) || (itemType() == ImageFrame) || (itemType() == OSGFrame))
1891 					p->setupPolygon(&PoLine);
1892 				if (NamedLStyle.isEmpty())
1893 				{
1894 					ScPattern *strokePattern = m_Doc->checkedPattern(patternStrokeVal);
1895 					if (strokePattern)
1896 					{
1897 						if (patternStrokePath)
1898 						{
1899 							QPainterPath guidePath = PoLine.toQPainterPath(false);
1900 							DrawStrokePattern(p, guidePath);
1901 						}
1902 						else
1903 						{
1904 							p->setPattern(strokePattern, patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY);
1905 							p->setStrokeMode(ScPainter::Pattern);
1906 							p->strokePath();
1907 						}
1908 					}
1909 					else if (GrTypeStroke > 0)
1910 					{
1911 						if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal)))
1912 							gradientStrokeVal.clear();
1913 						if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal)))
1914 							stroke_gradient = m_Doc->docGradients[gradientStrokeVal];
1915 						if (stroke_gradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
1916 						{
1917 							if (lineColor() != CommonStrings::None)
1918 							{
1919 								p->setBrush(m_strokeQColor);
1920 								p->setStrokeMode(ScPainter::Solid);
1921 							}
1922 							else
1923 							{
1924 								no_stroke = true;
1925 								p->setStrokeMode(ScPainter::None);
1926 							}
1927 						}
1928 						else
1929 						{
1930 							p->setStrokeMode(ScPainter::Gradient);
1931 							p->stroke_gradient = stroke_gradient;
1932 							p->stroke_gradient.setRepeatMethod(GrStrokeExtend);
1933 							if (GrTypeStroke == Gradient_Linear)
1934 								p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew);
1935 							else
1936 								p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew);
1937 						}
1938 						p->strokePath();
1939 					}
1940 					else if (lineColor() != CommonStrings::None)
1941 					{
1942 						p->setStrokeMode(ScPainter::Solid);
1943 						p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
1944 						if (DashValues.count() != 0)
1945 							p->setDash(DashValues, DashOffset);
1946 						p->strokePath();
1947 					}
1948 					else
1949 						no_stroke = true;
1950 					if (lineTransparency() > 0.9)
1951 						no_stroke = true;
1952 				}
1953 				else
1954 				{
1955 					p->setStrokeMode(ScPainter::Solid);
1956 					multiLine ml = m_Doc->docLineStyles[NamedLStyle];
1957 					QColor tmp;
1958 					for (int it = ml.size()-1; it > -1; it--)
1959 					{
1960 						struct SingleLine& sl = ml[it];
1961 						// Qt4 if ((!sl.Color != CommonStrings::None) && (sl.Width != 0))
1962 						if (sl.Color != CommonStrings::None) // && (sl.Width != 0))
1963 						{
1964 							SetQColor(&tmp, sl.Color, sl.Shade);
1965 							p->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash), static_cast<Qt::PenCapStyle>(sl.LineEnd), static_cast<Qt::PenJoinStyle>(sl.LineJoin));
1966 							p->strokePath();
1967 						}
1968 					}
1969 				}
1970 				p->setBlendModeStroke(0);
1971 			}
1972 		}
1973 	}
1974 	p->setFillMode(ScPainter::Solid);
1975 	p->setBlendModeFill(0);
1976 	p->setStrokeMode(ScPainter::Solid);
1977 	p->setBlendModeStroke(0);
1978 	p->restore();
1979 }
1980 
DrawObj_Decoration(ScPainter * p)1981 void PageItem::DrawObj_Decoration(ScPainter *p)
1982 {
1983 	p->save();
1984 //	p->setAntialiasing(false);
1985 	if (!isEmbedded)
1986 		p->translate(m_xPos, m_yPos);
1987 	p->rotate(m_rotation);
1988 	if ((!isEmbedded) && (!m_Doc->RePos))
1989 	{
1990 		double scpInv = 0;
1991 		if (!isGroup())
1992 		{
1993 			if ((drawFrame()) && (m_Doc->guidesPrefs().framesShown) && ((itemType() == ImageFrame) || (itemType() == LatexFrame) || (itemType() == OSGFrame) || (itemType() == PathText)) && (no_stroke))
1994 			{
1995 				p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1996 				if ((isBookmark) || (m_isAnnotation))
1997 					p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameAnnotationColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1998 				if ((m_backBox != nullptr) || (m_nextBox != nullptr))
1999 					p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLinkColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2000 				if (m_Locked)
2001 					p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLockColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2002 				p->setFillMode(ScPainter::None);
2003 				if (itemType() == PathText)
2004 				{
2005 					if (Clip.count() != 0)
2006 					{
2007 						FPointArray tclip;
2008 						FPoint np = FPoint(Clip.point(0));
2009 						tclip.resize(2);
2010 						tclip.setPoint(0, np);
2011 						tclip.setPoint(1, np);
2012 						for (int a = 1; a < Clip.size(); ++a)
2013 						{
2014 							np = FPoint(Clip.point(a));
2015 							tclip.putPoints(tclip.size(), 4, np.x(), np.y(), np.x(), np.y(), np.x(), np.y(), np.x(), np.y());
2016 						}
2017 						np = FPoint(Clip.point(0));
2018 						tclip.putPoints(tclip.size(), 2, np.x(), np.y(), np.x(), np.y());
2019 						p->setupPolygon(&tclip);
2020 					}
2021 				}
2022 				else
2023 					p->setupSharpPolygon(&PoLine);
2024 				p->strokePath();
2025 			}
2026 		}
2027 		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
2028 		{
2029 			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
2030 			p->setupSharpPolygon(&ContourLine);
2031 			p->strokePath();
2032 		}
2033 		if (itemType() == ImageFrame)
2034 		{
2035 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
2036 			double maxres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].maxResolution;
2037 			bool checkres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].checkResolution;
2038 			if  ((((72.0 / imageXScale()) < minres)
2039 				|| ((72.0 / imageYScale()) < minres)
2040 				|| ((72.0 / imageXScale()) > maxres)
2041 				|| ((72.0 / imageYScale()) > maxres))
2042 				&& (isRaster) && (checkres) && (!m_Doc->drawAsPreview) && (PrefsManager::instance().appPrefs.displayPrefs.showVerifierWarningsOnCanvas))
2043 			{
2044 				double ofx = m_width - 22.0;
2045 				double ofy = m_height - 22.0;
2046 				if ((m_width > 40) && (m_height > 40))
2047 				{
2048 					p->save();
2049 					p->translate(ofx, ofy);
2050 					QImage ico = IconManager::instance().loadPixmap("22/dialog-warning.png").toImage();
2051 					p->drawImage(&ico);
2052 					p->restore();
2053 				}
2054 			}
2055 		}
2056 		if ((m_Doc->guidesPrefs().layerMarkersShown) &&
2057 			(m_Doc->layerCount() > 1) &&
2058 			(!m_Doc->layerOutline(m_layerID)) &&
2059 			(!isGroupChild()) &&
2060 			(!m_Doc->drawAsPreview))
2061 		{
2062 			p->setPen(Qt::black, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2063 			p->setPenOpacity(1.0);
2064 			p->setBrush(m_Doc->layerMarker(m_layerID));
2065 			p->setBrushOpacity(1.0);
2066 			p->setFillMode(ScPainter::Solid);
2067 			double ofwh = 10;
2068 			double ofx = m_width - ofwh/2;
2069 			double ofy = m_height - ofwh*3;
2070 			p->drawSharpRect(ofx, ofy, ofwh, ofwh);
2071 		}
2072 		if (no_fill && no_stroke && m_Doc->guidesPrefs().framesShown)
2073 		{
2074 			p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2075 			if (m_Locked)
2076 				p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLockColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
2077 			p->setFillMode(ScPainter::None);
2078 			p->drawSharpRect(0, 0, m_width, m_height);
2079 			no_fill = false;
2080 			no_stroke = false;
2081 		}
2082 		//CB disabled for now
2083 		//if (m_Doc->m_Selection->findItem(this)!=-1)
2084 		//	drawLockedMarker(p);
2085 	}
2086 	FrameOnly = false;
2087 //	p->setAntialiasing(true);
2088 	p->restore();
2089 }
2090 
DrawObj_Embedded(ScPainter * p,QRectF cullingArea,const CharStyle & style,PageItem * cembedded)2091 void PageItem::DrawObj_Embedded(ScPainter *p, QRectF cullingArea, const CharStyle& style, PageItem* cembedded)
2092 {
2093 	if (!cembedded)
2094 		return;
2095 	QList<PageItem*> emG;
2096 	emG.clear();
2097 	emG.append(cembedded);
2098 	for (int em = 0; em < emG.count(); ++em)
2099 	{
2100 		PageItem* embedded = emG.at(em);
2101 		p->save();
2102 		double x = embedded->xPos();
2103 		double y = embedded->yPos();
2104 		embedded->m_xPos = embedded->gXpos;
2105 		embedded->m_yPos = (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos;
2106 		p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
2107 		if (style.baselineOffset() != 0)
2108 		{
2109 			p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
2110 			embedded->m_yPos -= embedded->gHeight * (style.baselineOffset() / 1000.0);
2111 		}
2112 		p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
2113 		embedded->invalid = true;
2114 		double pws = embedded->m_lineWidth;
2115 		embedded->DrawObj_Pre(p);
2116 		switch (embedded->itemType())
2117 		{
2118 			case ImageFrame:
2119 			case TextFrame:
2120 			case LatexFrame:
2121 			case OSGFrame:
2122 			case Polygon:
2123 			case PathText:
2124 			case Symbol:
2125 			case Group:
2126 			case RegularPolygon:
2127 			case Arc:
2128 			case Table:
2129 				embedded->DrawObj_Item(p, cullingArea);
2130 				break;
2131 			case Line:
2132 			case PolyLine:
2133 			case Spiral:
2134 				embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
2135 				embedded->DrawObj_Item(p, cullingArea);
2136 				break;
2137 			default:
2138 				break;
2139 		}
2140 		embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
2141 		embedded->DrawObj_Post(p);
2142 		embedded->m_xPos = x;
2143 		embedded->m_yPos = y;
2144 		p->restore();
2145 		embedded->m_lineWidth = pws;
2146 	}
2147 	if (m_Doc->guidesPrefs().framesShown)
2148 	{
2149 		p->save();
2150 		p->translate(0, -(cembedded->m_height * (style.scaleV() / 1000.0)));
2151 		if (style.baselineOffset() != 0)
2152 			p->translate(0, -cembedded->m_height * (style.baselineOffset() / 1000.0));
2153 		p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
2154 		p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
2155 		p->setFillMode(ScPainter::None);
2156 		p->drawSharpRect(0, 0, cembedded->m_width, cembedded->m_height);
2157 		p->restore();
2158 	}
2159 }
2160 
DrawStrokePattern(ScPainter * p,QPainterPath & path)2161 void PageItem::DrawStrokePattern(ScPainter *p, QPainterPath &path)
2162 {
2163 	ScPattern pat = m_Doc->docPatterns[patternStrokeVal];
2164 	double pLen = path.length() - ((pat.width / 2.0) * (patternStrokeScaleX / 100.0));
2165 	double adv = pat.width * patternStrokeScaleX / 100.0 * patternStrokeSpace;
2166 	double xpos = patternStrokeOffsetX * patternStrokeScaleX / 100.0;
2167 	while (xpos < pLen)
2168 	{
2169 		double currPerc = path.percentAtLength(xpos);
2170 		double currAngle = path.angleAtPercent(currPerc);
2171 		if (currAngle <= 180.0)
2172 			currAngle *= -1.0;
2173 		else
2174 			currAngle = 360.0 - currAngle;
2175 		QPointF currPoint = path.pointAtPercent(currPerc);
2176 		p->save();
2177 		p->translate(currPoint.x(), currPoint.y());
2178 		p->rotate(currAngle);
2179 		QTransform savWM = p->worldMatrix();
2180 		QTransform trans;
2181 		trans.translate(0.0, patternStrokeOffsetY);
2182 		trans.rotate(patternStrokeRotation);
2183 		trans.shear(-patternStrokeSkewX, patternStrokeSkewY);
2184 		trans.scale(patternStrokeScaleX / 100.0, patternStrokeScaleY / 100.0);
2185 		trans.translate(-pat.width / 2.0, -pat.height / 2.0);
2186 		if (patternStrokeMirrorX)
2187 		{
2188 			trans.translate(pat.width, 0);
2189 			trans.scale(-1, 1);
2190 		}
2191 		if (patternStrokeMirrorY)
2192 		{
2193 			trans.translate(0, pat.height);
2194 			trans.scale(1, -1);
2195 		}
2196 		trans *= savWM;
2197 		p->setWorldMatrix(trans);
2198 		for (int em = 0; em < pat.items.count(); ++em)
2199 		{
2200 			PageItem* embedded = pat.items.at(em);
2201 			p->save();
2202 			p->translate(embedded->gXpos, embedded->gYpos);
2203 			embedded->isEmbedded = true;
2204 			embedded->invalid = true;
2205 			embedded->DrawObj(p, QRectF());
2206 			embedded->isEmbedded = false;
2207 			p->restore();
2208 		}
2209 		p->setWorldMatrix(savWM);
2210 		xpos += adv;
2211 		p->restore();
2212 	}
2213 	p->newPath();
2214 }
2215 
DrawSoftShadow(ScPainter * p)2216 void PageItem::DrawSoftShadow(ScPainter *p)
2217 {
2218 	if (m_softShadowColor == CommonStrings::None)
2219 		return;
2220 	double lwCorr = m_lineWidth;
2221 	double sc = p->zoomFactor();
2222 	if ((m_lineWidth * sc) < 1)
2223 		lwCorr = 0;
2224 	const ScColor& col = m_Doc->PageColors[m_softShadowColor];
2225 	QColor tmp = ScColorEngine::getShadeColorProof(col, m_Doc, m_softShadowShade);
2226 	if (m_Doc->viewAsPreview)
2227 	{
2228 		VisionDefectColor defect;
2229 		tmp = defect.convertDefect(tmp, m_Doc->previewVisual);
2230 	}
2231 	p->save();
2232 	if (m_softShadowHasObjectTransparency)
2233 		p->beginLayer(1.0 - fillTransparency(), m_softShadowBlendMode);
2234 	else
2235 		p->beginLayer(1.0 - m_softShadowOpacity, m_softShadowBlendMode);
2236 	if (!hasFill())
2237 	{
2238 		double xOffset = isEmbedded ? m_softShadowXOffset : (m_softShadowXOffset - m_xPos);
2239 		double yOffset = isEmbedded ? m_softShadowYOffset : (m_softShadowYOffset - m_yPos);
2240 		double fillTrans_Old = fillTransparency();
2241 		double lineTrans_Old = lineTransparency();
2242 		bool   hasSoftShadow_Old = hasSoftShadow();
2243 		double rotation_Old = m_rotation;
2244 		m_fillTransparency = 0.0;
2245 		m_lineTransparency = 0.0;
2246 		m_rotation = 0;
2247 		m_hasSoftShadow = false;
2248 		p->save();
2249 		p->translate(xOffset, yOffset);
2250 		DrawObj(p, QRectF());
2251 		p->colorizeAlpha(tmp);
2252 		if (m_softShadowBlurRadius > 0)
2253 			p->blur(m_softShadowBlurRadius * sc);
2254 		p->restore();
2255 		if (m_softShadowErasedByObject)
2256 		{
2257 			p->save();
2258 			FPointArray sh = PoLine.copy();
2259 			p->beginLayer(1.0, 18, &sh);
2260 			p->translate(xOffset - m_softShadowXOffset, yOffset - m_softShadowYOffset);
2261 			DrawObj(p, QRectF());
2262 			p->endLayer();
2263 			p->restore();
2264 		}
2265 		m_fillTransparency = fillTrans_Old;
2266 		m_lineTransparency = lineTrans_Old;
2267 		m_hasSoftShadow = hasSoftShadow_Old;
2268 		m_rotation = rotation_Old;
2269 	}
2270 	else
2271 	{
2272 		FPointArray sh = PoLine.copy();
2273 		sh.translate(m_softShadowXOffset, m_softShadowYOffset);
2274 		p->setupPolygon(&sh);
2275 		p->setBrush(tmp);
2276 		p->setFillMode(ScPainter::Solid);
2277 		p->fillPath();
2278 		if (hasStroke())
2279 		{
2280 			p->setStrokeMode(ScPainter::Solid);
2281 			p->setPen(tmp, lwCorr, PLineArt, PLineEnd, PLineJoin);
2282 			p->strokePath();
2283 		}
2284 		if (m_softShadowBlurRadius > 0)
2285 			p->blur(m_softShadowBlurRadius * sc);
2286 		if (m_softShadowErasedByObject)
2287 		{
2288 			sh = PoLine.copy();
2289 			p->setupPolygon(&sh);
2290 			p->setBrush(tmp);
2291 			p->setFillMode(ScPainter::Solid);
2292 			p->setBlendModeFill(19);
2293 			p->fillPath();
2294 			if (hasStroke())
2295 			{
2296 				p->setBlendModeStroke(19);
2297 				p->setStrokeMode(ScPainter::Solid);
2298 				p->setPen(tmp, lwCorr, PLineArt, PLineEnd, PLineJoin);
2299 				p->strokePath();
2300 			}
2301 		}
2302 	}
2303 	p->endLayer();
2304 	p->restore();
2305 }
2306 
DrawObj_toImage(double maxSize,int options)2307 QImage PageItem::DrawObj_toImage(double maxSize, int options)
2308 {
2309 	bool isEmbedded_Old = isEmbedded;
2310 	double rotation_Old = m_rotation;
2311 	double minx =  std::numeric_limits<double>::max();
2312 	double miny =  std::numeric_limits<double>::max();
2313 	double maxx = -std::numeric_limits<double>::max();
2314 	double maxy = -std::numeric_limits<double>::max();
2315 	double x1, x2, y1, y2;
2316 	if (options & NoRotation)
2317 		m_rotation = 0.0;
2318 	getVisualBoundingRect(&x1, &y1, &x2, &y2);
2319 	m_rotation = rotation_Old;
2320 	double maxAdd = 0;
2321 	if (hasSoftShadow() && !(options & NoSoftShadow))
2322 		maxAdd = qMax(fabs(softShadowXOffset()), fabs(softShadowYOffset())) + softShadowBlurRadius();
2323 	minx = qMin(minx, x1) - maxAdd;
2324 	miny = qMin(miny, y1) - maxAdd;
2325 	maxx = qMax(maxx, x2) + maxAdd;
2326 	maxy = qMax(maxy, y2) + maxAdd;
2327 	double igXpos = xPos() - minx;
2328 	double igYpos = yPos() - miny;
2329 	double igWidth = maxx - minx;
2330 	double igHeight = maxy - miny;
2331 	double sc = maxSize / qMax(igWidth, igHeight);
2332 	bool savedFlag = m_Doc->guidesPrefs().framesShown;
2333 	m_Doc->guidesPrefs().framesShown = false;
2334 	QImage retImg = QImage(qMax(qRound(igWidth * sc), 1), qMax(qRound(igHeight * sc), 1), QImage::Format_ARGB32_Premultiplied);
2335 	retImg.fill( qRgba(0, 0, 0, 0) );
2336 	ScPainter *painter = new ScPainter(&retImg, retImg.width(), retImg.height(), 1, 0);
2337 	painter->setZoomFactor(sc);
2338 	painter->save();
2339 	painter->translate(igXpos, igYpos);
2340 	if (options & NoRotation)
2341 		painter->rotate(-m_rotation);
2342 	if (invalid)
2343 		layout();
2344 	isEmbedded = true;
2345 	DrawObj(painter, QRectF());
2346 	painter->restore();
2347 	painter->end();
2348 	delete painter;
2349 	m_Doc->guidesPrefs().framesShown = savedFlag;
2350 	isEmbedded = isEmbedded_Old;
2351 	if ((isEmbedded_Old != isEmbedded) && (isTextFrame() || isPathText()))
2352 	{
2353 		invalid = true;
2354 		layout();
2355 	}
2356 	return retImg;
2357 }
2358 
DrawObj_toImage(QList<PageItem * > & emG,double scaling)2359 QImage PageItem::DrawObj_toImage(QList<PageItem*> &emG, double scaling)
2360 {
2361 	bool isEmbedded_Old = isEmbedded;
2362 	bool savedFlag = m_Doc->guidesPrefs().framesShown;
2363 	m_Doc->guidesPrefs().framesShown = false;
2364 	QImage retImg = QImage(qRound(gWidth * scaling), qRound(gHeight * scaling), QImage::Format_ARGB32_Premultiplied);
2365 	retImg.fill( qRgba(0, 0, 0, 0) );
2366 	ScPainter *painter = new ScPainter(&retImg, retImg.width(), retImg.height(), 1, 0);
2367 	painter->setZoomFactor(scaling);
2368 	for (int em = 0; em < emG.count(); ++em)
2369 	{
2370 		PageItem* embedded = emG.at(em);
2371 		painter->save();
2372 		painter->translate(embedded->gXpos, embedded->gYpos);
2373 		embedded->isEmbedded = true;
2374 		embedded->invalid = true;
2375 		embedded->DrawObj(painter, QRectF());
2376 		embedded->isEmbedded = false;
2377 		painter->restore();
2378 	}
2379 	painter->end();
2380 	delete painter;
2381 	m_Doc->guidesPrefs().framesShown = savedFlag;
2382 	isEmbedded = isEmbedded_Old;
2383 	return retImg;
2384 }
2385 
SetQColor(QColor * tmp,const QString & colorName,double shad)2386 void PageItem::SetQColor(QColor *tmp, const QString& colorName, double shad)
2387 {
2388 	if (colorName == CommonStrings::None)
2389 		return;
2390 
2391 	const ScColor& col = m_Doc->PageColors[colorName];
2392 	*tmp = ScColorEngine::getShadeColorProof(col, m_Doc, shad);
2393 	if (m_Doc->viewAsPreview)
2394 	{
2395 		VisionDefectColor defect;
2396 		*tmp = defect.convertDefect(*tmp, m_Doc->previewVisual);
2397 	}
2398 }
2399 
DrawPolyL(QPainter * p,const QPolygon & pts)2400 void PageItem::DrawPolyL(QPainter *p, const QPolygon& pts)
2401 {
2402 	if (Segments.count() == 0)
2403 	{
2404 		p->drawPolygon(pts);
2405 		return;
2406 	}
2407 
2408 	QList<uint>::Iterator it2end = Segments.end();
2409 	uint firstVal = 0;
2410 	for (QList<uint>::Iterator it2 = Segments.begin(); it2 != it2end; ++it2)
2411 	{
2412 		p->drawPolygon(pts.constData() + firstVal, (*it2) - firstVal);
2413 		firstVal = (*it2);
2414 	}
2415 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
2416 }
2417 
setItemName(const QString & newName)2418 void PageItem::setItemName(const QString& newName)
2419 {
2420 	if (m_itemName == newName || newName.isEmpty())
2421 		return;
2422 	QString oldName = m_itemName;
2423 	m_itemName = generateUniqueCopyName(newName);
2424 	AutoName=false;
2425 	if (UndoManager::undoEnabled())
2426 	{
2427 		SimpleState *ss = new SimpleState(Um::Rename, QString(Um::FromTo).arg(oldName, newName));
2428 		ss->set("OLD_NAME", oldName);
2429 		ss->set("NEW_NAME", newName);
2430 		undoManager->action(this, ss);
2431 	}
2432 	setUName(m_itemName); // set the name for the UndoObject too
2433 }
2434 
setGradient(const QString & newGradient)2435 void PageItem::setGradient(const QString &newGradient)
2436 {
2437 	if (m_gradientName == newGradient)
2438 		return;
2439 	m_gradientName = newGradient;
2440 	if (m_Doc->docGradients.contains(m_gradientName))
2441 		fill_gradient = m_Doc->docGradients[m_gradientName];
2442 }
2443 
setMaskGradient(const VGradient & grad)2444 void PageItem::setMaskGradient(const VGradient& grad)
2445 {
2446 	if (mask_gradient==grad)
2447 		return;
2448 	if (UndoManager::undoEnabled())
2449 	{
2450 		ScItemState<QPair<VGradient, VGradient> >* is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
2451 		is->set("MASK_GRAD");
2452 		is->setItem(qMakePair(mask_gradient, grad));
2453 		undoManager->action(this,is);
2454 	}
2455 	mask_gradient=grad;
2456 }
2457 
setFillGradient(const VGradient & grad)2458 void PageItem::setFillGradient(const VGradient& grad)
2459 {
2460 	if (fill_gradient==grad)
2461 		return;
2462 	if (UndoManager::undoEnabled())
2463 	{
2464 		ScItemState<QPair<VGradient,VGradient> > *is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
2465 		is->set("FILL_GRAD");
2466 		is->setItem(qMakePair(fill_gradient, grad));
2467 		undoManager->action(this,is);
2468 	}
2469 	fill_gradient=grad;
2470 }
2471 
setStrokeGradient(const VGradient & grad)2472 void PageItem::setStrokeGradient(const VGradient& grad)
2473 {
2474 	if (stroke_gradient==grad)
2475 		return;
2476 	if (UndoManager::undoEnabled())
2477 	{
2478 		ScItemState<QPair<VGradient,VGradient> > *is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
2479 		is->set("STROKE_GRAD");
2480 		is->setItem(qMakePair(stroke_gradient, grad));
2481 		undoManager->action(this,is);
2482 	}
2483 	stroke_gradient=grad;
2484 }
2485 
setPattern(const QString & newPattern)2486 void PageItem::setPattern(const QString &newPattern)
2487 {
2488 	if (m_patternName != newPattern)
2489 		m_patternName = newPattern;
2490 }
2491 
set4ColorGeometry(FPoint c1,FPoint c2,FPoint c3,FPoint c4)2492 void PageItem::set4ColorGeometry(FPoint c1, FPoint c2, FPoint c3, FPoint c4)
2493 {
2494 	GrControl1 = c1;
2495 	GrControl2 = c2;
2496 	GrControl3 = c3;
2497 	GrControl4 = c4;
2498 }
2499 
setDiamondGeometry(const FPoint & c1,const FPoint & c2,const FPoint & c3,const FPoint & c4,const FPoint & c5)2500 void PageItem::setDiamondGeometry(const FPoint& c1, const FPoint& c2, const FPoint& c3, const FPoint& c4, const FPoint& c5)
2501 {
2502 	GrControl1 = c1;
2503 	GrControl2 = c2;
2504 	GrControl3 = c3;
2505 	GrControl4 = c4;
2506 	GrControl5 = c5;
2507 }
2508 
set4ColorTransparency(double t1,double t2,double t3,double t4)2509 void PageItem::set4ColorTransparency(double t1, double t2, double t3, double t4)
2510 {
2511 	UndoTransaction trans;
2512 	if (UndoManager::undoEnabled())
2513 		trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal,QString(), Um::IFill);
2514 	setGradientTransp1(t1);
2515 	setGradientTransp2(t2);
2516 	setGradientTransp3(t3);
2517 	setGradientTransp4(t4);
2518 	if (trans)
2519 		trans.commit();
2520 }
2521 
set4ColorShade(int t1,int t2,int t3,int t4)2522 void PageItem::set4ColorShade(int t1, int t2, int t3, int t4)
2523 {
2524 	UndoTransaction trans;
2525 	if (UndoManager::undoEnabled())
2526 		trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal, QString(), Um::IFill);
2527 	setGradientShade1(t1);
2528 	setGradientShade2(t2);
2529 	setGradientShade3(t3);
2530 	setGradientShade4(t4);
2531 	if (trans)
2532 		trans.commit();
2533 }
2534 
set4ColorColors(const QString & col1,const QString & col2,const QString & col3,const QString & col4)2535 void PageItem::set4ColorColors(const QString& col1, const QString& col2, const QString& col3, const QString& col4)
2536 {
2537 	QColor tmp;
2538 	UndoTransaction trans;
2539 	if (UndoManager::undoEnabled())
2540 		trans = undoManager->beginTransaction(Um::Selection,Um::IFill, Um::GradVal, QString(), Um::IFill);
2541 	setGradientCol1(col1);
2542 	if (GrColorP1 != CommonStrings::None)
2543 	{
2544 		if (!m_Doc->PageColors.contains(GrColorP1))
2545 		{
2546 			switch (itemType())
2547 			{
2548 				case ImageFrame:
2549 				case LatexFrame:
2550 				case OSGFrame:
2551 					setGradientCol1(m_Doc->itemToolPrefs().imageFillColor);
2552 					break;
2553 				case TextFrame:
2554 				case PathText:
2555 					setGradientCol1(m_Doc->itemToolPrefs().textFillColor);
2556 					break;
2557 				case Line:
2558 				case PolyLine:
2559 				case Polygon:
2560 				case RegularPolygon:
2561 				case Arc:
2562 				case Spiral:
2563 					setGradientCol1(m_Doc->itemToolPrefs().shapeFillColor);
2564 					break;
2565 				default:
2566 					break;
2567 			}
2568 		}
2569 		const ScColor& col = m_Doc->PageColors[GrColorP1];
2570 		tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol1Shade);
2571 		tmp.setAlphaF(GrCol1transp);
2572 		setGradientColor1(tmp);
2573 	}
2574 	else
2575 		setGradientColor1(QColor(0, 0, 0, 0));
2576 	if (m_Doc->viewAsPreview)
2577 	{
2578 		VisionDefectColor defect;
2579 		setGradientColor1(defect.convertDefect(m_grQColorP1, m_Doc->previewVisual));
2580 	}
2581 	setGradientCol2(col2);
2582 	if (GrColorP2 != CommonStrings::None)
2583 	{
2584 		if (!m_Doc->PageColors.contains(GrColorP2))
2585 		{
2586 			switch (itemType())
2587 			{
2588 				case ImageFrame:
2589 				case LatexFrame:
2590 				case OSGFrame:
2591 					setGradientCol2(m_Doc->itemToolPrefs().imageFillColor);
2592 					break;
2593 				case TextFrame:
2594 				case PathText:
2595 					setGradientCol2(m_Doc->itemToolPrefs().textFillColor);
2596 					break;
2597 				case Line:
2598 				case PolyLine:
2599 				case Polygon:
2600 				case RegularPolygon:
2601 				case Arc:
2602 				case Spiral:
2603 					setGradientCol2(m_Doc->itemToolPrefs().shapeFillColor);
2604 					break;
2605 				default:
2606 					break;
2607 			}
2608 		}
2609 		const ScColor& col = m_Doc->PageColors[GrColorP2];
2610 		tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol2Shade);
2611 		tmp.setAlphaF(GrCol2transp);
2612 		setGradientColor2(tmp);
2613 	}
2614 	else
2615 		setGradientColor2(QColor(0, 0, 0, 0));
2616 	if (m_Doc->viewAsPreview)
2617 	{
2618 		VisionDefectColor defect;
2619 		setGradientColor2(defect.convertDefect(m_grQColorP2, m_Doc->previewVisual));
2620 	}
2621 	setGradientCol3(col3);
2622 	if (GrColorP3 != CommonStrings::None)
2623 	{
2624 		if (!m_Doc->PageColors.contains(GrColorP3))
2625 		{
2626 			switch (itemType())
2627 			{
2628 				case ImageFrame:
2629 				case LatexFrame:
2630 				case OSGFrame:
2631 					setGradientCol3(m_Doc->itemToolPrefs().imageFillColor);
2632 					break;
2633 				case TextFrame:
2634 				case PathText:
2635 					setGradientCol3(m_Doc->itemToolPrefs().textFillColor);
2636 					break;
2637 				case Line:
2638 				case PolyLine:
2639 				case Polygon:
2640 				case RegularPolygon:
2641 				case Arc:
2642 				case Spiral:
2643 					setGradientCol3(m_Doc->itemToolPrefs().shapeFillColor);
2644 					break;
2645 				default:
2646 					break;
2647 			}
2648 		}
2649 		const ScColor& col = m_Doc->PageColors[GrColorP3];
2650 		tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol3Shade);
2651 		tmp.setAlphaF(GrCol3transp);
2652 		setGradientColor3(tmp);
2653 	}
2654 	else
2655 		setGradientColor3(QColor(0, 0, 0, 0));
2656 	if (m_Doc->viewAsPreview)
2657 	{
2658 		VisionDefectColor defect;
2659 		setGradientColor3(defect.convertDefect(m_grQColorP3, m_Doc->previewVisual));
2660 	}
2661 	setGradientCol4(col4);
2662 	if (GrColorP4 != CommonStrings::None)
2663 	{
2664 		if (!m_Doc->PageColors.contains(GrColorP4))
2665 		{
2666 			switch (itemType())
2667 			{
2668 				case ImageFrame:
2669 				case LatexFrame:
2670 				case OSGFrame:
2671 					setGradientCol4(m_Doc->itemToolPrefs().imageFillColor);
2672 					break;
2673 				case TextFrame:
2674 				case PathText:
2675 					setGradientCol4(m_Doc->itemToolPrefs().textFillColor);
2676 					break;
2677 				case Line:
2678 				case PolyLine:
2679 				case Polygon:
2680 				case RegularPolygon:
2681 				case Arc:
2682 				case Spiral:
2683 					setGradientCol4(m_Doc->itemToolPrefs().shapeFillColor);
2684 					break;
2685 				default:
2686 					break;
2687 			}
2688 		}
2689 		const ScColor& col = m_Doc->PageColors[GrColorP4];
2690 		tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol4Shade);
2691 		tmp.setAlphaF(GrCol4transp);
2692 		setGradientColor4(tmp);
2693 	}
2694 	else
2695 		setGradientColor4(QColor(0, 0, 0, 0));
2696 	if (m_Doc->viewAsPreview)
2697 	{
2698 		VisionDefectColor defect;
2699 		setGradientColor4(defect.convertDefect(m_grQColorP4, m_Doc->previewVisual));
2700 	}
2701 	if (trans)
2702 		trans.commit();
2703 }
2704 
get4ColorGeometry(FPoint & c1,FPoint & c2,FPoint & c3,FPoint & c4)2705 void PageItem::get4ColorGeometry(FPoint& c1, FPoint& c2, FPoint& c3, FPoint& c4)
2706 {
2707 	c1 = GrControl1;
2708 	c2 = GrControl2;
2709 	c3 = GrControl3;
2710 	c4 = GrControl4;
2711 }
2712 
get4ColorTransparency(double & t1,double & t2,double & t3,double & t4)2713 void PageItem::get4ColorTransparency(double &t1, double &t2, double &t3, double &t4)
2714 {
2715 	t1 = GrCol1transp;
2716 	t2 = GrCol2transp;
2717 	t3 = GrCol3transp;
2718 	t4 = GrCol4transp;
2719 }
2720 
get4ColorColors(QString & col1,QString & col2,QString & col3,QString & col4)2721 void PageItem::get4ColorColors(QString &col1, QString &col2, QString &col3, QString &col4)
2722 {
2723 	col1 = GrColorP1;
2724 	col2 = GrColorP2;
2725 	col3 = GrColorP3;
2726 	col4 = GrColorP4;
2727 }
2728 
setMeshPointColor(int x,int y,const QString & color,int shade,double transparency,bool forPatch)2729 void PageItem::setMeshPointColor(int x, int y, const QString& color, int shade, double transparency, bool forPatch)
2730 {
2731 	QString MColor(color);
2732 	QColor MQColor;
2733 	if (MColor != CommonStrings::None)
2734 	{
2735 		if (!m_Doc->PageColors.contains(MColor))
2736 		{
2737 			switch (itemType())
2738 			{
2739 				case ImageFrame:
2740 				case LatexFrame:
2741 				case OSGFrame:
2742 					MColor = m_Doc->itemToolPrefs().imageFillColor;
2743 					break;
2744 				case TextFrame:
2745 				case PathText:
2746 					MColor = m_Doc->itemToolPrefs().textFillColor;
2747 					break;
2748 				case Line:
2749 				case PolyLine:
2750 				case Polygon:
2751 				case RegularPolygon:
2752 				case Arc:
2753 				case Spiral:
2754 					MColor = m_Doc->itemToolPrefs().shapeFillColor;
2755 					break;
2756 				default:
2757 					break;
2758 			}
2759 		}
2760 		const ScColor& col = m_Doc->PageColors[MColor];
2761 		MQColor = ScColorEngine::getShadeColorProof(col, m_Doc, shade);
2762 		MQColor.setAlphaF(transparency);
2763 	}
2764 	else
2765 		MQColor = QColor(0, 0, 0, 0);
2766 	if (m_Doc->viewAsPreview)
2767 	{
2768 		VisionDefectColor defect;
2769 		MQColor = defect.convertDefect(MQColor, m_Doc->previewVisual);
2770 	}
2771 	MeshPoint *mp = nullptr;
2772 	if (forPatch)
2773 	{
2774 		meshGradientPatch *patch = &meshGradientPatches[x];
2775 		switch (y)
2776 		{
2777 			case 1:
2778 				mp = &(patch->TL);
2779 				break;
2780 			case 2:
2781 				mp = &(patch->TR);
2782 				break;
2783 			case 3:
2784 				mp = &(patch->BR);
2785 				break;
2786 			case 4:
2787 				mp = &(patch->BL);
2788 				break;
2789 		}
2790 
2791 		UndoTransaction trans;
2792 		if (UndoManager::undoEnabled())
2793 		{
2794 			trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal, QString(), Um::IFill);
2795 			ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2796 			ss->set("GRAD_MESH_COLOR");
2797 			ss->set("X",x);
2798 			ss->set("Y",y);
2799 			ss->set("PATCH",true);
2800 			ss->set("OLD_COLOR_NAME",mp->colorName);
2801 			ss->set("NEW_COLOR_NAME",MColor);
2802 			ss->setItem(qMakePair(mp->color,MQColor));
2803 			ss->set("OLD_SHADE",mp->shade);
2804 			ss->set("NEW_SHADE",shade);
2805 			ss->set("OLD_TRANSP",mp->transparency);
2806 			ss->set("NEW_TRANSP",transparency);
2807 			undoManager->action(this, ss);
2808 		}
2809 		mp->colorName = MColor;
2810 		mp->color = MQColor;
2811 		mp->shade = shade;
2812 		mp->transparency = transparency;
2813 		FPoint xx = mp->gridPoint;
2814 		for (int col = 0; col < meshGradientPatches.count(); col++)
2815 		{
2816 			if (col != x)
2817 			{
2818 				if (meshGradientPatches[col].TL.gridPoint == xx)
2819 				{
2820 					mp = &(meshGradientPatches[col].TL);
2821 					if (UndoManager::undoEnabled())
2822 					{
2823 						ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2824 						ss->set("GRAD_MESH_COLOR");
2825 						ss->set("X",col);
2826 						ss->set("Y",1);
2827 						ss->set("PATCH",true);
2828 						ss->set("OLD_COLOR_NAME",mp->colorName);
2829 						ss->set("NEW_COLOR_NAME",MColor);
2830 						ss->setItem(qMakePair(mp->color,MQColor));
2831 						ss->set("OLD_SHADE",mp->shade);
2832 						ss->set("NEW_SHADE",shade);
2833 						ss->set("OLD_TRANSP",mp->transparency);
2834 						ss->set("NEW_TRANSP",transparency);
2835 						undoManager->action(this, ss);
2836 					}
2837 					mp->colorName = MColor;
2838 					mp->color = MQColor;
2839 					mp->shade = shade;
2840 					mp->transparency = transparency;
2841 				}
2842 				if (meshGradientPatches[col].TR.gridPoint == xx)
2843 				{
2844 					mp = &(meshGradientPatches[col].TR);
2845 					if (UndoManager::undoEnabled())
2846 					{
2847 						ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2848 						ss->set("GRAD_MESH_COLOR");
2849 						ss->set("X",col);
2850 						ss->set("Y",2);
2851 						ss->set("PATCH",true);
2852 						ss->set("OLD_COLOR_NAME",mp->colorName);
2853 						ss->set("NEW_COLOR_NAME",MColor);
2854 						ss->setItem(qMakePair(mp->color,MQColor));
2855 						ss->set("OLD_SHADE",mp->shade);
2856 						ss->set("NEW_SHADE",shade);
2857 						ss->set("OLD_TRANSP",mp->transparency);
2858 						ss->set("NEW_TRANSP",transparency);
2859 						undoManager->action(this, ss);
2860 					}
2861 					mp->colorName = MColor;
2862 					mp->color = MQColor;
2863 					mp->shade = shade;
2864 					mp->transparency = transparency;
2865 				}
2866 				if (meshGradientPatches[col].BR.gridPoint == xx)
2867 				{
2868 					mp = &(meshGradientPatches[col].BR);
2869 					if (UndoManager::undoEnabled())
2870 					{
2871 						ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2872 						ss->set("GRAD_MESH_COLOR");
2873 						ss->set("X",col);
2874 						ss->set("Y",3);
2875 						ss->set("PATCH",true);
2876 						ss->set("OLD_COLOR_NAME",mp->colorName);
2877 						ss->set("NEW_COLOR_NAME",MColor);
2878 						ss->setItem(qMakePair(mp->color,MQColor));
2879 						ss->set("OLD_SHADE",mp->shade);
2880 						ss->set("NEW_SHADE",shade);
2881 						ss->set("OLD_TRANSP",mp->transparency);
2882 						ss->set("NEW_TRANSP",transparency);
2883 						undoManager->action(this, ss);
2884 					}
2885 					mp->colorName = MColor;
2886 					mp->color = MQColor;
2887 					mp->shade = shade;
2888 					mp->transparency = transparency;
2889 				}
2890 				if (meshGradientPatches[col].BL.gridPoint == xx)
2891 				{
2892 					mp = &(meshGradientPatches[col].BL);
2893 					if (UndoManager::undoEnabled())
2894 					{
2895 						ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2896 						ss->set("GRAD_MESH_COLOR");
2897 						ss->set("X",col);
2898 						ss->set("Y",4);
2899 						ss->set("PATCH",true);
2900 						ss->set("OLD_COLOR_NAME",mp->colorName);
2901 						ss->set("NEW_COLOR_NAME",MColor);
2902 						ss->setItem(qMakePair(mp->color,MQColor));
2903 						ss->set("OLD_SHADE",mp->shade);
2904 						ss->set("NEW_SHADE",shade);
2905 						ss->set("OLD_TRANSP",mp->transparency);
2906 						ss->set("NEW_TRANSP",transparency);
2907 						undoManager->action(this, ss);
2908 					}
2909 					mp->colorName = MColor;
2910 					mp->color = MQColor;
2911 					mp->shade = shade;
2912 					mp->transparency = transparency;
2913 				}
2914 			}
2915 		}
2916 		if (trans)
2917 			trans.commit();
2918 	}
2919 	else
2920 	{
2921 		if ((x > -1) && (y > -1))
2922 		{
2923 			mp = &(meshGradientArray[x][y]);
2924 			if (UndoManager::undoEnabled())
2925 			{
2926 				ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
2927 				ss->set("GRAD_MESH_COLOR");
2928 				ss->set("X",x);
2929 				ss->set("Y",y);
2930 				ss->set("PATCH",false);
2931 				ss->set("OLD_COLOR_NAME",mp->colorName);
2932 				ss->set("NEW_COLOR_NAME",MColor);
2933 				ss->setItem(qMakePair(mp->color,MQColor));
2934 				ss->set("OLD_SHADE",mp->shade);
2935 				ss->set("NEW_SHADE",shade);
2936 				ss->set("OLD_TRANSP",mp->transparency);
2937 				ss->set("NEW_TRANSP",transparency);
2938 				undoManager->action(this, ss);
2939 			}
2940 			mp->colorName = MColor;
2941 			mp->color = MQColor;
2942 			mp->shade = shade;
2943 			mp->transparency = transparency;
2944 		}
2945 	}
2946 }
2947 
createGradientMesh(int rows,int cols)2948 void PageItem::createGradientMesh(int rows, int cols)
2949 {
2950 	QString MColor(m_fillColor);
2951 	QColor MQColor;
2952 	if (m_fillColor != CommonStrings::None)
2953 	{
2954 		if (!m_Doc->PageColors.contains(m_fillColor))
2955 		{
2956 			switch (itemType())
2957 			{
2958 				case ImageFrame:
2959 				case LatexFrame:
2960 				case OSGFrame:
2961 					MColor = m_Doc->itemToolPrefs().imageFillColor;
2962 					break;
2963 				case TextFrame:
2964 				case PathText:
2965 					MColor = m_Doc->itemToolPrefs().textFillColor;
2966 					break;
2967 				case Line:
2968 				case PolyLine:
2969 				case Polygon:
2970 				case RegularPolygon:
2971 				case Arc:
2972 				case Spiral:
2973 					MColor = m_Doc->itemToolPrefs().shapeFillColor;
2974 					break;
2975 				default:
2976 					break;
2977 			}
2978 		}
2979 		const ScColor& col = m_Doc->PageColors[MColor];
2980 		MQColor = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
2981 		MQColor.setAlphaF(1.0);
2982 	}
2983 	else
2984 		MQColor = QColor(0, 0, 0, 0);
2985 	if (m_Doc->viewAsPreview)
2986 	{
2987 		VisionDefectColor defect;
2988 		MQColor = defect.convertDefect(MQColor, m_Doc->previewVisual);
2989 	}
2990 	if (UndoManager::undoEnabled())
2991 	{
2992 		ScItemState<QList<QList<MeshPoint> > >* is = new ScItemState<QList<QList<MeshPoint> > >(Um::MeshGradient);
2993 		is->set("CREATE_MESH_GRAD");
2994 		is->set("ROW",rows);
2995 		is->set("COL",cols);
2996 		is->setItem(meshGradientArray);
2997 		undoManager->action(this,is);
2998 	}
2999 	meshGradientArray.clear();
3000 	if (rows == 0 || cols == 0)
3001 		qFatal("PageItem::createGradientMesh: rows or cols is 0");
3002 	double xoffs = m_width / static_cast<double>(cols);
3003 	double yoffs = m_height / static_cast<double>(rows);
3004 	for (int x = 0; x < rows + 1; x++)
3005 	{
3006 		QList<MeshPoint> mgList;
3007 		mgList.reserve(cols + 1);
3008 		for (int y = 0; y < cols + 1; y++)
3009 		{
3010 			MeshPoint mgP;
3011 			mgP.resetTo(FPoint(y * xoffs, x * yoffs));
3012 			mgP.transparency = 1.0;
3013 			mgP.shade = 100;
3014 			mgP.colorName = MColor;
3015 			mgP.color = MQColor;
3016 			mgList.append(mgP);
3017 		}
3018 		meshGradientArray.append(mgList);
3019 	}
3020 }
3021 
resetGradientMesh()3022 void PageItem::resetGradientMesh()
3023 {
3024 	int rows = meshGradientArray.count();
3025 	int cols = meshGradientArray[0].count();
3026 	if (UndoManager::undoEnabled())
3027 	{
3028 		ScItemState<QList<QList<MeshPoint> > > *is = new ScItemState<QList<QList<MeshPoint> > >(Um::ResetControlPoints);
3029 		is->set("RESET_MESH_GRAD");
3030 		is->setItem(meshGradientArray);
3031 		undoManager->action(this,is);
3032 	}
3033 	double xoffs = m_width / static_cast<double>(cols-1);
3034 	double yoffs = m_height / static_cast<double>(rows-1);
3035 	for (int x = 0; x < rows; x++)
3036 		for (int y = 0; y < cols; y++)
3037 			meshGradientArray[x][y].resetTo(FPoint(y * xoffs, x * yoffs));
3038 }
3039 
meshToShape()3040 void PageItem::meshToShape()
3041 {
3042 	FPointArray Coords;
3043 	Coords.resize(0);
3044 	Coords.svgInit();
3045 	int rows = meshGradientArray.count() - 1;
3046 	int cols = meshGradientArray[0].count() - 1;
3047 	QList<MeshPoint> mpList;
3048 	mpList = meshGradientArray[0];
3049 	Coords.svgMoveTo(mpList[0].gridPoint.x(), mpList[0].gridPoint.y());
3050 	for (int m = 0; m < mpList.count()-1; m++)
3051 	{
3052 		Coords.svgCurveToCubic(mpList[m].controlRight.x(), mpList[m].controlRight.y(),
3053 								mpList[m+1].controlLeft.x(), mpList[m+1].controlLeft.y(),
3054 								mpList[m+1].gridPoint.x(), mpList[m+1].gridPoint.y());
3055 	}
3056 	for (int m = 0; m < rows; m++)
3057 	{
3058 		Coords.svgCurveToCubic(meshGradientArray[m][cols].controlBottom.x(), meshGradientArray[m][cols].controlBottom.y(),
3059 								meshGradientArray[m+1][cols].controlTop.x(), meshGradientArray[m+1][cols].controlTop.y(),
3060 								meshGradientArray[m+1][cols].gridPoint.x(), meshGradientArray[m+1][cols].gridPoint.y());
3061 	}
3062 	mpList = meshGradientArray[rows];
3063 	for (int m = cols; m > 0; m--)
3064 	{
3065 		Coords.svgCurveToCubic(mpList[m].controlLeft.x(), mpList[m].controlLeft.y(),
3066 								mpList[m-1].controlRight.x(), mpList[m-1].controlRight.y(),
3067 								mpList[m-1].gridPoint.x(), mpList[m-1].gridPoint.y());
3068 	}
3069 	for (int m = rows; m > 0; m--)
3070 	{
3071 		Coords.svgCurveToCubic(meshGradientArray[m][0].controlTop.x(), meshGradientArray[m][0].controlTop.y(),
3072 								meshGradientArray[m-1][0].controlBottom.x(), meshGradientArray[m-1][0].controlBottom.y(),
3073 								meshGradientArray[m-1][0].gridPoint.x(), meshGradientArray[m-1][0].gridPoint.y());
3074 	}
3075 
3076 	UndoTransaction trans;
3077 	if (UndoManager::undoEnabled())
3078 	{
3079 		trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::ChangeMeshGradient, QString(), Um::IFill);
3080 		ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> > *ism = new ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> >(Um::ChangeMeshGradient, QString(), Um::IFill);
3081 		ism->set("MOVE_MESH_GRAD");
3082 		ism->setItem(qMakePair(meshGradientArray,PoLine));
3083 		ism->set("OLDB",OldB2);
3084 		ism->set("OLDH",OldH2);
3085 		ism->set("FRAME_TYPE",FrameType);
3086 		undoManager->action(this, ism);
3087 	}
3088 	QList<QList<MeshPoint> > meshGradientArrayOld = meshGradientArray;
3089 	PoLine = Coords.copy();
3090 	double oldX = m_xPos;
3091 	double oldY = m_yPos;
3092 	ClipEdited = true;
3093 	FrameType = 3;
3094 	FPoint wh = getMaxClipF(&PoLine);
3095 	setWidthHeight(wh.x(),wh.y());
3096 	m_Doc->adjustItemSize(this);
3097 	OldB2 = width();
3098 	OldH2 = height();
3099 	updateClip();
3100 	meshGradientArray = meshGradientArrayOld;
3101 	double dx = oldX - m_xPos;
3102 	double dy = oldY - m_yPos;
3103 	for (int x = 0; x < rows+1; x++)
3104 		for (int y = 0; y < cols+1; y++)
3105 			meshGradientArray[x][y].moveRel(dx, dy);
3106 	if (UndoManager::undoEnabled())
3107 	{
3108 		ScItemState<FPointArray> *is = new ScItemState<FPointArray>(Um::ResetContourLine, QString(), Um::IBorder);
3109 		is->set("RESET_CONTOUR");
3110 		is->setItem(ContourLine);
3111 		undoManager->action(this, is);
3112 	}
3113 	ContourLine = PoLine.copy();
3114 	if (trans)
3115 		trans.commit();
3116 }
3117 
createConicalMesh()3118 void PageItem::createConicalMesh()
3119 {
3120 	VGradient gradient;
3121 	gradient.clearStops();
3122 	if (fill_gradient.stops() < 2)
3123 	{
3124 		fill_gradient.clearStops();
3125 		const ScColor& col = m_Doc->PageColors["Black"];
3126 		QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
3127 		fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
3128 		const ScColor& col2 = m_Doc->PageColors["White"];
3129 		qcol = ScColorEngine::getRGBColor(col2, m_Doc);
3130 		fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, "White", 100);
3131 	}
3132 	QList<VColorStop*> cstops = fill_gradient.colorStops();
3133 	double lastStop = -1.0;
3134 	double actualStop = 0.0;
3135 	bool isFirst = true;
3136 	for (int cst = 0; cst < fill_gradient.stops(); ++cst)
3137 	{
3138 		actualStop = cstops.at(cst)->rampPoint;
3139 		if ((actualStop == lastStop) && (!isFirst))
3140 			continue;
3141 		if (isFirst)
3142 		{
3143 			if (actualStop != 0.0)
3144 			{
3145 				gradient.addStop(cstops.at(cst)->color, 0, 0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3146 				if (actualStop <= 0.25)
3147 					gradient.addStop(cstops.at(cst)->color, cstops.at(cst)->rampPoint, cstops.at(cst)->midPoint, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3148 				else
3149 				{
3150 					double actDist = 0.25;
3151 					do
3152 					{
3153 						gradient.addStop(cstops.at(cst)->color, actDist, actDist, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3154 						actDist += 0.25;
3155 					}
3156 					while (actualStop > actDist);
3157 					gradient.addStop(cstops.at(cst)->color, cstops.at(cst)->rampPoint, cstops.at(cst)->midPoint, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3158 				}
3159 			}
3160 			else
3161 				gradient.addStop(cstops.at(cst)->color, cstops.at(cst)->rampPoint, cstops.at(cst)->midPoint, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3162 			isFirst = false;
3163 			lastStop = actualStop;
3164 			continue;
3165 		}
3166 		isFirst = false;
3167 		if (actualStop - lastStop <= 0.25)
3168 			gradient.addStop(cstops.at(cst)->color, cstops.at(cst)->rampPoint, cstops.at(cst)->midPoint, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3169 		else
3170 		{
3171 			double actDist = lastStop + 0.25;
3172 			do
3173 			{
3174 				gradient.addStop(computeInBetweenStop(cstops.at(cst-1), cstops.at(cst), actDist));
3175 				actDist += 0.25;
3176 			}
3177 			while (actualStop > actDist);
3178 			gradient.addStop(cstops.at(cst)->color, cstops.at(cst)->rampPoint, cstops.at(cst)->midPoint, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3179 		}
3180 		if ((cst == fill_gradient.stops()-1) && (actualStop < 1.0))
3181 		{
3182 			double distToGo = 1.0 - actualStop;
3183 			if (distToGo <= 0.25)
3184 				gradient.addStop(cstops.at(cst)->color, 1.0, 1.0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3185 			else
3186 			{
3187 				do
3188 				{
3189 					double actDist = actualStop + 0.25;
3190 					gradient.addStop(cstops.at(cst)->color, actDist, actDist, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3191 					distToGo -= 0.25;
3192 					actDist += 0.25;
3193 				}
3194 				while (distToGo >= 0.25);
3195 				gradient.addStop(cstops.at(cst)->color, 1.0, 1.0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
3196 			}
3197 			break;
3198 		}
3199 		lastStop = actualStop;
3200 	}
3201 	meshGradientArray.clear();
3202 	QList<MeshPoint> mgList1;
3203 	QList<MeshPoint> mgList2;
3204 	MeshPoint mgP1, mgP2, mgP3, mgP4;
3205 	QPainterPath path;
3206 	FPointArray arcPath;
3207 	QLineF angLin = QLineF(QPointF(GrStartX, GrStartY), QPointF(GrEndX, GrEndY));
3208 	double startAngle = angLin.angle();
3209 	double radius = angLin.length();
3210 	double radius2 = radius * 2.0;
3211 	QList<VColorStop*> rstops = gradient.colorStops();
3212 	if (rstops.count() < 2)
3213 	{
3214 		const VColorStop* firstStop = rstops.at(0);
3215 		if (firstStop->rampPoint > 0)
3216 		{
3217 			VColorStop* newStop = new VColorStop(*firstStop);
3218 			newStop->rampPoint = 0;
3219 			rstops.prepend(newStop);
3220 		}
3221 		if (firstStop->rampPoint < 1.0)
3222 		{
3223 			VColorStop* newStop = new VColorStop(*firstStop);
3224 			newStop->rampPoint = 1.0;
3225 			rstops.append(newStop);
3226 		}
3227 	}
3228 	double stepAngle = 360 * rstops.at(1)->rampPoint;
3229 	path.arcMoveTo(-radius, -radius, radius2, radius2, 0);
3230 	path.arcTo(-radius, -radius, radius2, radius2, 0, -stepAngle);
3231 	QTransform mm;
3232 	mm.rotate(-startAngle);
3233 	path = mm.map(path);
3234 	QTransform mr;
3235 	mr.scale(1.0, GrScale);
3236 	path = mr.map(path);
3237 	arcPath.fromQPainterPath(path);
3238 	arcPath.translate(GrStartX, GrStartY);
3239 	QPointF foc = QPointF(GrFocalX, GrFocalY);
3240 	QTransform qmatrix;
3241 	qmatrix.translate(GrStartX, GrStartY);
3242 	qmatrix.rotate(-startAngle);
3243 	qmatrix.translate(0, GrStartY * (1.0 - GrScale));
3244 	qmatrix.translate(-GrStartX, -GrStartY);
3245 	qmatrix.scale(1, GrScale);
3246 	foc = qmatrix.map(foc);
3247 	mgP1.resetTo(arcPath.point(0));
3248 	mgP1.controlRight = arcPath.point(1);
3249 	mgP1.transparency = rstops.at(0)->opacity;
3250 	mgP1.shade = rstops.at(0)->shade;
3251 	mgP1.colorName = rstops.at(0)->name;
3252 	mgP1.color = rstops.at(0)->color;
3253 	mgP1.color.setAlphaF(mgP1.transparency);
3254 	mgList1.append(mgP1);
3255 
3256 	mgP2.resetTo(arcPath.point(2));
3257 	mgP2.controlLeft = arcPath.point(3);
3258 	mgP2.transparency = rstops.at(1)->opacity;
3259 	mgP2.shade = rstops.at(1)->shade;
3260 	mgP2.colorName = rstops.at(1)->name;
3261 	mgP2.color = rstops.at(1)->color;
3262 	mgP2.color.setAlphaF(mgP2.transparency);
3263 
3264 	mgP3.resetTo(FPoint(foc.x(), foc.y()));
3265 	mgP3.transparency = rstops.at(0)->opacity;
3266 	mgP3.shade = rstops.at(0)->shade;
3267 	mgP3.colorName = rstops.at(0)->name;
3268 	mgP3.color = rstops.at(0)->color;
3269 	mgP3.color.setAlphaF(mgP3.transparency);
3270 
3271 	mgList2.append(mgP3);
3272 	mgP3.transparency = rstops.at(1)->opacity;
3273 	mgP3.shade = rstops.at(1)->shade;
3274 	mgP3.colorName = rstops.at(1)->name;
3275 	mgP3.color = rstops.at(1)->color;
3276 	mgP3.color.setAlphaF(mgP3.transparency);
3277 	mgList2.append(mgP3);
3278 	startAngle -= stepAngle;
3279 	for (int rst = 2; rst < gradient.stops(); ++rst)
3280 	{
3281 		stepAngle = 360 * (rstops.at(rst)->rampPoint - rstops.at(rst-1)->rampPoint);
3282 		if (stepAngle <= 0)
3283 			continue;
3284 		path = QPainterPath();
3285 		arcPath.resize(0);
3286 		path.arcMoveTo(-radius, -radius, radius2, radius2, 0);
3287 		path.arcTo(-radius, -radius, radius2, radius2, 0, -stepAngle);
3288 		QTransform mm;
3289 		mm.rotate(-startAngle);
3290 		QTransform mr;
3291 		mr.scale(1.0, GrScale);
3292 		path = mm.map(path);
3293 		path = mr.map(path);
3294 		arcPath.fromQPainterPath(path);
3295 		arcPath.translate(GrStartX, GrStartY);
3296 		mgP2.controlRight = arcPath.point(1);
3297 		mgList1.append(mgP2);
3298 
3299 		mgP2.resetTo(arcPath.point(2));
3300 		mgP2.controlLeft = arcPath.point(3);
3301 		mgP2.transparency = rstops.at(rst)->opacity;
3302 		mgP2.shade = rstops.at(rst)->shade;
3303 		mgP2.colorName = rstops.at(rst)->name;
3304 		mgP2.color = rstops.at(rst)->color;
3305 		mgP2.color.setAlphaF(mgP2.transparency);
3306 
3307 		mgP3.transparency = rstops.at(rst)->opacity;
3308 		mgP3.shade = rstops.at(rst)->shade;
3309 		mgP3.colorName = rstops.at(rst)->name;
3310 		mgP3.color = rstops.at(rst)->color;
3311 		mgP3.color.setAlphaF(mgP3.transparency);
3312 		mgList2.append(mgP3);
3313 		startAngle -= stepAngle;
3314 	}
3315 	mgList1.append(mgP2);
3316 	meshGradientArray.append(mgList1);
3317 	meshGradientArray.append(mgList2);
3318 }
3319 
computeInBetweenStop(VColorStop * last,VColorStop * actual,double t)3320 VColorStop PageItem::computeInBetweenStop(VColorStop* last, VColorStop* actual, double t)
3321 {
3322 	double dist = actual->rampPoint - last->rampPoint;
3323 	double perc = (t - last->rampPoint) / dist;
3324 	double Rn = ((actual->color.redF() - last->color.redF()) * perc) + last->color.redF();
3325 	double Gn = ((actual->color.greenF() - last->color.greenF()) * perc) + last->color.greenF();
3326 	double Bn = ((actual->color.blueF() - last->color.blueF()) * perc) + last->color.blueF();
3327 	QColor color;
3328 	color.setRgbF(Rn, Gn, Bn);
3329 	double opacity = ((actual->opacity - last->opacity) * perc) + last->opacity;
3330 	int shade = qRound(((actual->shade - last->shade) * perc) + last->shade);
3331 	QString name = last->name + actual->name + QString("%1").arg(perc);
3332 	return VColorStop(t, t, color, opacity, name, shade);
3333 }
3334 
gradientVector(double & startX,double & startY,double & endX,double & endY,double & focalX,double & focalY,double & scale,double & skew) const3335 void PageItem::gradientVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
3336 {
3337 	startX = GrStartX;
3338 	startY = GrStartY;
3339 	endX   = GrEndX;
3340 	endY   = GrEndY;
3341 	focalX = GrFocalX;
3342 	focalY = GrFocalY;
3343 	scale  = GrScale;
3344 	skew   = GrSkew;
3345 }
3346 
setGradientVector(double startX,double startY,double endX,double endY,double focalX,double focalY,double scale,double skew)3347 void PageItem::setGradientVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
3348 {
3349 	GrStartX = startX;
3350 	GrStartY = startY;
3351 	GrEndX   = endX;
3352 	GrEndY   = endY;
3353 	GrFocalX = focalX;
3354 	GrFocalY = focalY;
3355 	GrScale  = scale;
3356 	GrSkew   = skew;
3357 }
3358 
setStrokeGradient(const QString & newGradient)3359 void PageItem::setStrokeGradient(const QString &newGradient)
3360 {
3361 	if (gradientStrokeVal != newGradient)
3362 		gradientStrokeVal = newGradient;
3363 }
3364 
strokeGradientVector(double & startX,double & startY,double & endX,double & endY,double & focalX,double & focalY,double & scale,double & skew) const3365 void PageItem::strokeGradientVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
3366 {
3367 	startX = GrStrokeStartX;
3368 	startY = GrStrokeStartY;
3369 	endX   = GrStrokeEndX;
3370 	endY   = GrStrokeEndY;
3371 	focalX = GrStrokeFocalX;
3372 	focalY = GrStrokeFocalY;
3373 	scale  = GrStrokeScale;
3374 	skew   = GrStrokeSkew;
3375 }
3376 
setStrokeGradientVector(double startX,double startY,double endX,double endY,double focalX,double focalY,double scale,double skew)3377 void PageItem::setStrokeGradientVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
3378 {
3379 	GrStrokeStartX = startX;
3380 	GrStrokeStartY = startY;
3381 	GrStrokeEndX   = endX;
3382 	GrStrokeEndY   = endY;
3383 	GrStrokeFocalX = focalX;
3384 	GrStrokeFocalY = focalY;
3385 	GrStrokeScale  = scale;
3386 	GrStrokeSkew   = skew;
3387 }
3388 
setPatternTransform(double scaleX,double scaleY,double offsetX,double offsetY,double rotation,double skewX,double skewY)3389 void PageItem::setPatternTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY)
3390 {
3391 	patternScaleX = scaleX;
3392 	patternScaleY = scaleY;
3393 	patternOffsetX = offsetX;
3394 	patternOffsetY = offsetY;
3395 	patternRotation = rotation;
3396 	patternSkewX = skewX;
3397 	patternSkewY = skewY;
3398 }
3399 
patternTransform(double & scaleX,double & scaleY,double & offsetX,double & offsetY,double & rotation,double & skewX,double & skewY) const3400 void PageItem::patternTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY) const
3401 {
3402 	 scaleX = patternScaleX;
3403 	 scaleY = patternScaleY;
3404 	 offsetX = patternOffsetX;
3405 	 offsetY = patternOffsetY;
3406 	 rotation = patternRotation;
3407 	 skewX = patternSkewX;
3408 	 skewY = patternSkewY;
3409 }
3410 
setPatternFlip(bool flipX,bool flipY)3411 void PageItem::setPatternFlip(bool flipX, bool flipY)
3412 {
3413 	patternMirrorX = flipX;
3414 	patternMirrorY = flipY;
3415 }
3416 
patternFlip(bool & flipX,bool & flipY)3417 void PageItem::patternFlip(bool &flipX, bool &flipY)
3418 {
3419 	flipX = patternMirrorX;
3420 	flipY = patternMirrorY;
3421 }
3422 
setMaskType(int val)3423 void PageItem::setMaskType(int val)
3424 {
3425 	if (GrMask == val)
3426 		return;
3427 	if (UndoManager::undoEnabled())
3428 	{
3429 		SimpleState *ss = new SimpleState(Um::GradTypeMask, QString(), Um::IFill);
3430 		ss->set("MASKTYPE");
3431 		ss->set("NEW", val);
3432 		ss->set("OLD", GrMask);
3433 		undoManager->action(this, ss);
3434 	}
3435 	GrMask = val;
3436 }
3437 
setGradientMask(const QString & newMask)3438 void PageItem::setGradientMask(const QString &newMask)
3439 {
3440 	if (gradientMaskVal != newMask)
3441 		gradientMaskVal = newMask;
3442 }
3443 
setPatternMask(const QString & newMask)3444 void PageItem::setPatternMask(const QString &newMask)
3445 {
3446 	if (patternMaskVal != newMask)
3447 		patternMaskVal = newMask;
3448 }
3449 
maskVector(double & startX,double & startY,double & endX,double & endY,double & focalX,double & focalY,double & scale,double & skew) const3450 void PageItem::maskVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
3451 {
3452 	startX = GrMaskStartX;
3453 	startY = GrMaskStartY;
3454 	endX   = GrMaskEndX;
3455 	endY   = GrMaskEndY;
3456 	focalX = GrMaskFocalX;
3457 	focalY = GrMaskFocalY;
3458 	scale  = GrMaskScale;
3459 	skew   = GrMaskSkew;
3460 }
3461 
setMaskVector(double startX,double startY,double endX,double endY,double focalX,double focalY,double scale,double skew)3462 void PageItem::setMaskVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
3463 {
3464 	GrMaskStartX = startX;
3465 	GrMaskStartY = startY;
3466 	GrMaskEndX   = endX;
3467 	GrMaskEndY   = endY;
3468 	GrMaskFocalX = focalX;
3469 	GrMaskFocalY = focalY;
3470 	GrMaskScale  = scale;
3471 	GrMaskSkew   = skew;
3472 }
3473 
maskTransform(double & scaleX,double & scaleY,double & offsetX,double & offsetY,double & rotation,double & skewX,double & skewY) const3474 void PageItem::maskTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY) const
3475 {
3476 	 scaleX = patternMaskScaleX;
3477 	 scaleY = patternMaskScaleY;
3478 	 offsetX = patternMaskOffsetX;
3479 	 offsetY = patternMaskOffsetY;
3480 	 rotation = patternMaskRotation;
3481 	 skewX = patternMaskSkewX;
3482 	 skewY = patternMaskSkewY;
3483 }
3484 
setMaskTransform(double scaleX,double scaleY,double offsetX,double offsetY,double rotation,double skewX,double skewY)3485 void PageItem::setMaskTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY)
3486 {
3487 	patternMaskScaleX = scaleX;
3488 	patternMaskScaleY = scaleY;
3489 	patternMaskOffsetX = offsetX;
3490 	patternMaskOffsetY = offsetY;
3491 	patternMaskRotation = rotation;
3492 	patternMaskSkewX = skewX;
3493 	patternMaskSkewY = skewY;
3494 }
3495 
setMaskFlip(bool flipX,bool flipY)3496 void PageItem::setMaskFlip(bool flipX, bool flipY)
3497 {
3498 	patternMaskMirrorX = flipX;
3499 	patternMaskMirrorY = flipY;
3500 }
3501 
maskFlip(bool & flipX,bool & flipY)3502 void PageItem::maskFlip(bool &flipX, bool &flipY)
3503 {
3504 	flipX = patternMaskMirrorX;
3505 	flipY = patternMaskMirrorY;
3506 }
3507 
setFillColor(const QString & newColor)3508 void PageItem::setFillColor(const QString &newColor)
3509 {
3510 	QString tmp = newColor;
3511 	if (tmp != CommonStrings::None)
3512 	{
3513 		if (!m_Doc->PageColors.contains(newColor))
3514 		{
3515 			switch (itemType())
3516 			{
3517 				case ImageFrame:
3518 				case LatexFrame:
3519 				case OSGFrame:
3520 					tmp = m_Doc->itemToolPrefs().imageFillColor;
3521 					break;
3522 				case TextFrame:
3523 				case PathText:
3524 					tmp = m_Doc->itemToolPrefs().textFillColor;
3525 					break;
3526 				case Line:
3527 				case PolyLine:
3528 				case Polygon:
3529 				case RegularPolygon:
3530 				case Arc:
3531 				case Spiral:
3532 					tmp = m_Doc->itemToolPrefs().shapeFillColor;
3533 					break;
3534 				default:
3535 					break;
3536 			}
3537 		}
3538 	}
3539 	if (m_fillColor == tmp)
3540 	{
3541 		setFillQColor();
3542 		return;
3543 	}
3544 	if (UndoManager::undoEnabled())
3545 	{
3546 		SimpleState *ss = new SimpleState(Um::SetFill,
3547 										  QString(Um::ColorFromTo).arg(m_fillColor, tmp),
3548                                           Um::IFill);
3549 		ss->set("FILL");
3550 		ss->set("OLD_FILL", m_fillColor);
3551 		ss->set("NEW_FILL", tmp);
3552 		undoManager->action(this, ss);
3553 	}
3554 	m_fillColor = tmp;
3555 	setFillQColor();
3556 }
3557 
setFillShade(double newShade)3558 void PageItem::setFillShade(double newShade)
3559 {
3560 	if (m_fillShade == newShade)
3561 	{
3562 		setFillQColor();
3563 		return;
3564 	}
3565 	if (UndoManager::undoEnabled())
3566 	{
3567 		SimpleState *ss = new SimpleState(Um::SetShade,
3568 										  QString(Um::FromTo).arg(m_fillShade).arg(newShade),
3569 										  Um::IShade);
3570 		ss->set("SHADE");
3571 		ss->set("OLD_SHADE", m_fillShade);
3572 		ss->set("NEW_SHADE", newShade);
3573 		undoManager->action(this, ss);
3574 	}
3575 	m_fillShade = newShade;
3576 	setFillQColor();
3577 }
3578 
setFillTransparency(double newTransparency)3579 void PageItem::setFillTransparency(double newTransparency)
3580 {
3581 	if (m_fillTransparency == newTransparency)
3582 		return; // nothing to do -> return
3583 	if (UndoManager::undoEnabled())
3584 	{
3585 		SimpleState *ss = new SimpleState(Um::Transparency,
3586 										  QString(Um::FromTo).arg(m_fillTransparency).arg(newTransparency),
3587 										  Um::ITransparency);
3588 		ss->set("TRANSPARENCY");
3589 		ss->set("OLD_TP", m_fillTransparency);
3590 		ss->set("NEW_TP", newTransparency);
3591 		undoManager->action(this, ss);
3592 	}
3593 	m_fillTransparency = newTransparency;
3594 }
3595 
setFillBlendmode(int newBlendmode)3596 void PageItem::setFillBlendmode(int newBlendmode)
3597 {
3598 	if (m_fillBlendMode == newBlendmode)
3599 		return; // nothing to do -> return
3600 	if (UndoManager::undoEnabled())
3601 	{
3602 		SimpleState *ss = new SimpleState(Um::BlendMode, nullptr, Um::IGroup);
3603 		ss->set("FILLBLENDMODE", newBlendmode);
3604 		ss->set("FILLBLENDMODE_OLD", m_fillBlendMode);
3605 		undoManager->action(this, ss);
3606 	}
3607 	m_fillBlendMode = newBlendmode;
3608 }
3609 
setLineColor(const QString & newColor)3610 void PageItem::setLineColor(const QString &newColor)
3611 {
3612 	QString tmp = newColor;
3613 	if (tmp != CommonStrings::None)
3614 	{
3615 		if (!m_Doc->PageColors.contains(newColor))
3616 		{
3617 			switch (itemType())
3618 			{
3619 				case TextFrame:
3620 				case PathText:
3621 					tmp = m_Doc->itemToolPrefs().textLineColor;
3622 					break;
3623 				case Line:
3624 					tmp = m_Doc->itemToolPrefs().lineColor;
3625 					break;
3626 				case PolyLine:
3627 				case Polygon:
3628 				case ImageFrame:
3629 				case LatexFrame:
3630 				case OSGFrame:
3631 				case RegularPolygon:
3632 				case Arc:
3633 				case Spiral:
3634 					tmp = m_Doc->itemToolPrefs().shapeLineColor;
3635 					break;
3636 				default:
3637 					break;
3638 			}
3639 		}
3640 	}
3641 	if (m_lineColor == tmp)
3642 	{
3643 		setLineQColor();
3644 		return;
3645 	}
3646 	if (UndoManager::undoEnabled())
3647 	{
3648 		SimpleState *ss = new SimpleState(Um::SetLineColor,
3649 										  QString(Um::ColorFromTo).arg(m_lineColor, tmp),
3650 										  Um::IFill);
3651 		ss->set("LINE_COLOR");
3652 		ss->set("OLD_COLOR", m_lineColor);
3653 		ss->set("NEW_COLOR", tmp);
3654 		undoManager->action(this, ss);
3655 	}
3656 	m_lineColor = tmp;
3657 	setLineQColor();
3658 }
3659 
setLineShade(double newShade)3660 void PageItem::setLineShade(double newShade)
3661 {
3662 	if (m_lineShade == newShade)
3663 	{
3664 		setLineQColor();
3665 		return;
3666 	}
3667 	if (UndoManager::undoEnabled())
3668 	{
3669 		SimpleState *ss = new SimpleState(Um::SetLineShade,
3670 										  QString(Um::FromTo).arg(m_lineShade).arg(newShade),
3671 										  Um::IShade);
3672 		ss->set("LINE_SHADE");
3673 		ss->set("OLD_SHADE", m_lineShade);
3674 		ss->set("NEW_SHADE", newShade);
3675 		undoManager->action(this, ss);
3676 	}
3677 	m_lineShade = newShade;
3678 	setLineQColor();
3679 }
3680 
setStrokePattern(const QString & newPattern)3681 void PageItem::setStrokePattern(const QString &newPattern)
3682 {
3683 	if (patternStrokeVal != newPattern)
3684 		patternStrokeVal = newPattern;
3685 }
3686 
setStrokePatternToPath(bool enable)3687 void PageItem::setStrokePatternToPath(bool enable)
3688 {
3689 	patternStrokePath = enable;
3690 }
3691 
isStrokePatternToPath()3692 bool PageItem::isStrokePatternToPath()
3693 {
3694 	return patternStrokePath;
3695 }
3696 
setStrokePatternTransform(double scaleX,double scaleY,double offsetX,double offsetY,double rotation,double skewX,double skewY,double space)3697 void PageItem::setStrokePatternTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, double space)
3698 {
3699 	patternStrokeScaleX = scaleX;
3700 	patternStrokeScaleY = scaleY;
3701 	patternStrokeOffsetX = offsetX;
3702 	patternStrokeOffsetY = offsetY;
3703 	patternStrokeRotation = rotation;
3704 	patternStrokeSkewX = skewX;
3705 	patternStrokeSkewY = skewY;
3706 	patternStrokeSpace = space;
3707 }
3708 
setStrokePatternFlip(bool flipX,bool flipY)3709 void PageItem::setStrokePatternFlip(bool flipX, bool flipY)
3710 {
3711 	patternStrokeMirrorX = flipX;
3712 	patternStrokeMirrorY = flipY;
3713 }
3714 
strokePatternFlip(bool & flipX,bool & flipY)3715 void PageItem::strokePatternFlip(bool &flipX, bool &flipY)
3716 {
3717 	flipX = patternStrokeMirrorX;
3718 	flipY = patternStrokeMirrorY;
3719 }
3720 
strokePatternTransform(double & scaleX,double & scaleY,double & offsetX,double & offsetY,double & rotation,double & skewX,double & skewY,double & space) const3721 void PageItem::strokePatternTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY, double &space) const
3722 {
3723 	scaleX = patternStrokeScaleX;
3724 	scaleY = patternStrokeScaleY;
3725 	offsetX = patternStrokeOffsetX;
3726 	offsetY = patternStrokeOffsetY;
3727 	rotation = patternStrokeRotation;
3728 	skewX = patternStrokeSkewX;
3729 	skewY = patternStrokeSkewY;
3730 	space = patternStrokeSpace;
3731 }
3732 
setLineQColor()3733 void PageItem::setLineQColor()
3734 {
3735 	if (m_lineColor != CommonStrings::None)
3736 	{
3737 		if (!m_Doc->PageColors.contains(m_lineColor))
3738 		{
3739 			switch (itemType())
3740 			{
3741 				case TextFrame:
3742 				case PathText:
3743 					m_lineColor = m_Doc->itemToolPrefs().textLineColor;
3744 					break;
3745 				case Line:
3746 					m_lineColor = m_Doc->itemToolPrefs().lineColor;
3747 					break;
3748 				case PolyLine:
3749 				case Polygon:
3750 				case ImageFrame:
3751 				case LatexFrame:
3752 				case OSGFrame:
3753 				case RegularPolygon:
3754 				case Arc:
3755 				case Spiral:
3756 					m_lineColor = m_Doc->itemToolPrefs().shapeLineColor;
3757 					break;
3758 				default:
3759 					break;
3760 			}
3761 		}
3762 		if (!m_Doc->PageColors.contains(m_lineColor))
3763 			m_lineColor = m_Doc->itemToolPrefs().shapeLineColor;
3764 		const ScColor& col = m_Doc->PageColors[m_lineColor];
3765 		m_strokeQColor = ScColorEngine::getShadeColorProof(col, m_Doc, m_lineShade);
3766 	}
3767 	if (m_Doc->viewAsPreview)
3768 	{
3769 		VisionDefectColor defect;
3770 		m_strokeQColor = defect.convertDefect(m_strokeQColor, m_Doc->previewVisual);
3771 	}
3772 }
3773 
setFillQColor()3774 void PageItem::setFillQColor()
3775 {
3776 	if (m_fillColor != CommonStrings::None)
3777 	{
3778 		if (!m_Doc->PageColors.contains(m_fillColor))
3779 		{
3780 			switch (itemType())
3781 			{
3782 				case ImageFrame:
3783 				case LatexFrame:
3784 				case OSGFrame:
3785 					m_fillColor = m_Doc->itemToolPrefs().imageFillColor;
3786 					break;
3787 				case TextFrame:
3788 				case PathText:
3789 					m_fillColor = m_Doc->itemToolPrefs().textFillColor;
3790 					break;
3791 				case Line:
3792 				case PolyLine:
3793 				case Polygon:
3794 				case RegularPolygon:
3795 				case Arc:
3796 				case Spiral:
3797 					m_fillColor = m_Doc->itemToolPrefs().shapeFillColor;
3798 					break;
3799 				default:
3800 					break;
3801 			}
3802 		}
3803 		const ScColor& col = m_Doc->PageColors[m_fillColor];
3804 		m_fillQColor = ScColorEngine::getShadeColorProof(col, m_Doc, m_fillShade);
3805 	}
3806 	if (m_Doc->viewAsPreview)
3807 	{
3808 		VisionDefectColor defect;
3809 		m_fillQColor = defect.convertDefect(m_fillQColor, m_Doc->previewVisual);
3810 	}
3811 }
3812 
setHatchParameters(int mode,double distance,double angle,bool useBackground,const QString & background,const QString & foreground)3813 void PageItem::setHatchParameters(int mode, double distance, double angle, bool useBackground, const QString& background, const QString& foreground)
3814 {
3815 	hatchType = mode;
3816 	hatchDistance = distance;
3817 	hatchAngle = angle;
3818 	hatchUseBackground = useBackground;
3819 	hatchBackground = background;
3820 	hatchForeground = foreground;
3821 	if (background != CommonStrings::None)
3822 	{
3823 		if (!m_Doc->PageColors.contains(background))
3824 			hatchBackgroundQ = QColor();
3825 		else
3826 		{
3827 			const ScColor& col = m_Doc->PageColors[background];
3828 			hatchBackgroundQ = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
3829 			if (m_Doc->viewAsPreview)
3830 			{
3831 				VisionDefectColor defect;
3832 				hatchBackgroundQ = defect.convertDefect(hatchBackgroundQ, m_Doc->previewVisual);
3833 			}
3834 		}
3835 	}
3836 	if (foreground != CommonStrings::None)
3837 	{
3838 		if (!m_Doc->PageColors.contains(foreground))
3839 			hatchForegroundQ = QColor();
3840 		else
3841 		{
3842 			const ScColor& col = m_Doc->PageColors[foreground];
3843 			hatchForegroundQ = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
3844 			if (m_Doc->viewAsPreview)
3845 			{
3846 				VisionDefectColor defect;
3847 				hatchForegroundQ = defect.convertDefect(hatchForegroundQ, m_Doc->previewVisual);
3848 			}
3849 		}
3850 	}
3851 }
3852 
setLineTransparency(double newTransparency)3853 void PageItem::setLineTransparency(double newTransparency)
3854 {
3855 	if (m_lineTransparency == newTransparency)
3856 		return; // nothing to do -> return
3857 	if (UndoManager::undoEnabled())
3858 	{
3859 		SimpleState *ss = new SimpleState(Um::LineTransparency,
3860 										  QString(Um::FromTo).arg(m_lineTransparency).arg(newTransparency),
3861 										  Um::ITransparency);
3862 		ss->set("LINE_TRANSPARENCY");
3863 		ss->set("OLD_TP", m_lineTransparency);
3864 		ss->set("NEW_TP", newTransparency);
3865 		undoManager->action(this, ss);
3866 	}
3867 	m_lineTransparency = newTransparency;
3868 }
3869 
setLineBlendmode(int newBlendmode)3870 void PageItem::setLineBlendmode(int newBlendmode)
3871 {
3872 	if (m_lineBlendMode == newBlendmode)
3873 		return; // nothing to do -> return
3874 	if (UndoManager::undoEnabled())
3875 	{
3876 		SimpleState *ss = new SimpleState(Um::BlendMode, nullptr, Um::IGroup);
3877 		ss->set("LINEBLENDMODE", newBlendmode);
3878 		ss->set("LINEBLENDMODE_OLD", m_lineBlendMode);
3879 		undoManager->action(this, ss);
3880 	}
3881 	m_lineBlendMode = newBlendmode;
3882 }
3883 
setLineStyle(Qt::PenStyle newStyle)3884 void PageItem::setLineStyle(Qt::PenStyle newStyle)
3885 {
3886 	if (PLineArt == newStyle)
3887 		return; // nothing to do -> return
3888 	if (UndoManager::undoEnabled())
3889 	{
3890 		SimpleState *ss = new SimpleState(Um::LineStyle, QString(), Um::ILineStyle);
3891 		ss->set("LINE_STYLE");
3892 		ss->set("OLD_STYLE", static_cast<int>(PLineArt));
3893 		ss->set("NEW_STYLE", static_cast<int>(newStyle));
3894 		undoManager->action(this, ss);
3895 	}
3896 	PLineArt = newStyle;
3897 }
3898 
setLineWidth(double newWidth)3899 void PageItem::setLineWidth(double newWidth)
3900 {
3901 	if ((m_lineWidth == newWidth) || (isGroup()))
3902 		return; // nothing to do -> return
3903 	if (UndoManager::undoEnabled())
3904 	{
3905 		SimpleState *ss = new SimpleState(Um::LineWidth,
3906 						QString(Um::FromTo).arg(m_lineWidth).arg(newWidth),Um::ILineStyle);
3907 		ss->set("LINE_WIDTH");
3908 		ss->set("OLD_LINEWIDTH", m_lineWidth);
3909 		ss->set("NEW_LINEWIDTH", newWidth);
3910 		undoManager->action(this, ss);
3911 	}
3912 	m_oldLineWidth=m_lineWidth;
3913 	m_lineWidth = newWidth;
3914 }
3915 
setLineEnd(Qt::PenCapStyle newStyle)3916 void PageItem::setLineEnd(Qt::PenCapStyle newStyle)
3917 {
3918 	if (PLineEnd == newStyle)
3919 		return; // nothing to do -> return
3920 	if (UndoManager::undoEnabled())
3921 	{
3922 		SimpleState *ss = new SimpleState(Um::LineEnd, QString(), Um::ILineStyle);
3923 		ss->set("LINE_END");
3924 		ss->set("OLD_STYLE", static_cast<int>(PLineEnd));
3925 		ss->set("NEW_STYLE", static_cast<int>(newStyle));
3926 		undoManager->action(this, ss);
3927 	}
3928 	PLineEnd = newStyle;
3929 }
3930 
setLineJoin(Qt::PenJoinStyle newStyle)3931 void PageItem::setLineJoin(Qt::PenJoinStyle newStyle)
3932 {
3933 	if (PLineJoin == newStyle)
3934 		return; // nothing to do -> return
3935 	if (UndoManager::undoEnabled())
3936 	{
3937 		SimpleState *ss = new SimpleState(Um::LineJoin, QString(), Um::ILineStyle);
3938 		ss->set("LINE_JOIN");
3939 		ss->set("OLD_STYLE", static_cast<int>(PLineJoin));
3940 		ss->set("NEW_STYLE", static_cast<int>(newStyle));
3941 		undoManager->action(this, ss);
3942 	}
3943 	PLineJoin = newStyle;
3944 }
3945 
setCustomLineStyle(const QString & newStyle)3946 void PageItem::setCustomLineStyle(const QString& newStyle)
3947 {
3948 	if (NamedLStyle == newStyle)
3949 		return; // nothing to do -> return
3950 	if (UndoManager::undoEnabled())
3951 	{
3952 		QString oldStyle = NamedLStyle.isEmpty() ? Um::NoStyle : NamedLStyle;
3953 		QString nStyle   = newStyle.isEmpty() ? Um::NoStyle : newStyle;
3954 		QString action   = newStyle.isEmpty() ? Um::NoLineStyle : Um::CustomLineStyle;
3955 		SimpleState *ss = new SimpleState(action, QString(Um::FromTo).arg(oldStyle, nStyle), Um::ILineStyle);
3956 		ss->set("CUSTOM_LINE_STYLE");
3957 		ss->set("OLD_STYLE", NamedLStyle);
3958 		ss->set("NEW_STYLE", newStyle);
3959 		undoManager->action(this, ss);
3960 	}
3961 	NamedLStyle = newStyle;
3962 }
3963 
setStartArrowIndex(int newIndex)3964 void PageItem::setStartArrowIndex(int newIndex)
3965 {
3966 	if (m_startArrowIndex == newIndex)
3967 		return; // nothing to do -> return
3968 	if (UndoManager::undoEnabled())
3969 	{
3970 		SimpleState *ss = new SimpleState(Um::StartArrow, QString(), Um::IArrow);
3971 		ss->set("START_ARROW");
3972 		ss->set("OLD_INDEX", m_startArrowIndex);
3973 		ss->set("NEW_INDEX", newIndex);
3974 		undoManager->action(this, ss);
3975 	}
3976 	m_startArrowIndex = newIndex;
3977 }
3978 
setEndArrowIndex(int newIndex)3979 void PageItem::setEndArrowIndex(int newIndex)
3980 {
3981 	if (m_endArrowIndex == newIndex)
3982 		return; // nothing to do -> return
3983 	if (UndoManager::undoEnabled())
3984 	{
3985 		SimpleState *ss = new SimpleState(Um::EndArrow, QString(), Um::IArrow);
3986 		ss->set("END_ARROW");
3987 		ss->set("OLD_INDEX", m_endArrowIndex);
3988 		ss->set("NEW_INDEX", newIndex);
3989 		undoManager->action(this, ss);
3990 	}
3991 	m_endArrowIndex = newIndex;
3992 }
3993 
setStartArrowScale(int newScale)3994 void PageItem::setStartArrowScale(int newScale)
3995 {
3996 	if (m_startArrowScale == newScale)
3997 		return; // nothing to do -> return
3998 	if (UndoManager::undoEnabled())
3999 	{
4000 		SimpleState *ss = new SimpleState(Um::StartArrowScale, QString(), Um::IArrow);
4001 		ss->set("START_ARROWSCALE");
4002 		ss->set("OLD_SCALE", m_startArrowScale);
4003 		ss->set("NEW_SCALE", newScale);
4004 		undoManager->action(this, ss);
4005 	}
4006 	m_startArrowScale = newScale;
4007 }
4008 
setEndArrowScale(int newScale)4009 void PageItem::setEndArrowScale(int newScale)
4010 {
4011 	if (m_endArrowScale == newScale)
4012 		return; // nothing to do -> return
4013 	if (UndoManager::undoEnabled())
4014 	{
4015 		SimpleState *ss = new SimpleState(Um::EndArrowScale, QString(), Um::IArrow);
4016 		ss->set("END_ARROWSCALE");
4017 		ss->set("OLD_SCALE", m_endArrowScale);
4018 		ss->set("NEW_SCALE", newScale);
4019 		undoManager->action(this, ss);
4020 	}
4021 	m_endArrowScale = newScale;
4022 }
4023 
setImageFlippedH(bool flipped)4024 void PageItem::setImageFlippedH(bool flipped)
4025 {
4026 	if (flipped != m_ImageIsFlippedH)
4027 		flipImageH();
4028 }
4029 
flipImageH()4030 void PageItem::flipImageH()
4031 {
4032 	if (UndoManager::undoEnabled())
4033 	{
4034 		SimpleState *ss = new SimpleState(Um::FlipH, nullptr, Um::IFlipH);
4035 		ss->set("IMAGEFLIPH");
4036 		undoManager->action(this, ss);
4037 	}
4038 	m_ImageIsFlippedH = !m_ImageIsFlippedH;
4039 }
4040 
setImageFlippedV(bool flipped)4041 void PageItem::setImageFlippedV(bool flipped)
4042 {
4043 	if (flipped != m_ImageIsFlippedV)
4044 		flipImageV();
4045 }
4046 
flipImageV()4047 void PageItem::flipImageV()
4048 {
4049 	if (UndoManager::undoEnabled())
4050 	{
4051 		SimpleState *ss = new SimpleState(Um::FlipV, nullptr, Um::IFlipV);
4052 		ss->set("IMAGEFLIPV");
4053 		undoManager->action(this, ss);
4054 	}
4055 	m_ImageIsFlippedV = !m_ImageIsFlippedV;
4056 }
4057 
setImageScalingMode(bool freeScale,bool keepRatio)4058 void PageItem::setImageScalingMode(bool freeScale, bool keepRatio)
4059 {
4060 	if (ScaleType == freeScale && AspectRatio == keepRatio)
4061 		return;
4062 	if (UndoManager::undoEnabled())
4063 	{
4064 		QString from = ScaleType ? Um::FreeScaling : Um::FrameSize;
4065 		from += ", ";
4066 		from += AspectRatio ? Um::KeepRatio : Um::BreakRatio;
4067 		QString to = freeScale ? Um::FreeScaling : Um::FrameSize;
4068 		to += ", ";
4069 		to += keepRatio ? Um::KeepRatio : Um::BreakRatio;
4070 		SimpleState *ss = new SimpleState(Um::ImageScaling, QString(Um::FromTo).arg(from, to), Um::IImageScaling);
4071 		ss->set("SCALE_MODE");
4072 		if (freeScale != ScaleType)
4073 		{
4074 			ss->set("SCALE_TYPE", freeScale);
4075 			if (!freeScale)
4076 			{
4077 				//if switching from free scaling to frame size
4078 				//in undo must be offset and scale saved
4079 				ss->set("OLD_IMAGEXOFFSET", m_imageXOffset);
4080 				ss->set("OLD_IMAGEYOFFSET", m_imageYOffset);
4081 				ss->set("OLD_IMAGEXSCALE", m_imageXScale);
4082 				ss->set("OLD_IMAGEYSCALE", m_imageYScale);
4083 			}
4084 		}
4085 		if (keepRatio != AspectRatio)
4086 			ss->set("ASPECT_RATIO", keepRatio);
4087 		undoManager->action(this, ss);
4088 	}
4089 	ScaleType = freeScale;
4090 	AspectRatio = keepRatio;
4091 	adjustPictScale();
4092 	update();
4093 }
4094 
setOverprint(bool val)4095 void PageItem::setOverprint(bool val)
4096 {
4097 	if (doOverprint == val)
4098 		return;
4099 
4100 	if (UndoManager::undoEnabled())
4101 	{
4102 		SimpleState *ss = new SimpleState(Um::Overprint, nullptr, Um::IGroup);
4103 		ss->set("OVERPRINT", val);
4104 		undoManager->action(this, ss);
4105 	}
4106 	doOverprint = val;
4107 }
4108 
setHasSoftShadow(bool val)4109 void PageItem::setHasSoftShadow(bool val)
4110 {
4111 	if (m_hasSoftShadow == val)
4112 		return;
4113 
4114 	if (UndoManager::undoEnabled())
4115 	{
4116 		SimpleState *ss = new SimpleState(Um::SoftShadow, nullptr, Um::IGroup);
4117 		ss->set("SOFT_SHADOW");
4118 		ss->set("NEW_VALUE", val);
4119 		ss->set("OLD_VALUE", m_hasSoftShadow);
4120 		undoManager->action(this, ss);
4121 	}
4122 	m_hasSoftShadow = val;
4123 }
4124 
setSoftShadowColor(const QString & val)4125 void PageItem::setSoftShadowColor(const QString &val)
4126 {
4127 	if (m_softShadowColor == val)
4128 		return;
4129 
4130 	if (UndoManager::undoEnabled())
4131 	{
4132 		SimpleState *ss = new SimpleState(Um::SoftShadowColor, nullptr, Um::IGroup);
4133 		ss->set("SOFT_SHADOW_COLOR");
4134 		ss->set("NEW_VALUE", val);
4135 		ss->set("OLD_VALUE", m_softShadowColor);
4136 		undoManager->action(this, ss);
4137 	}
4138 	m_softShadowColor = val;
4139 }
4140 
setSoftShadowShade(int val)4141 void PageItem::setSoftShadowShade(int val)
4142 {
4143 	if (m_softShadowShade == val)
4144 		return;
4145 
4146 	if (UndoManager::undoEnabled())
4147 	{
4148 		SimpleState *ss = new SimpleState(Um::SoftShadowShade, nullptr, Um::IGroup);
4149 		ss->set("SOFT_SHADOW_SHADE");
4150 		ss->set("NEW_VALUE", val);
4151 		ss->set("OLD_VALUE", m_softShadowShade);
4152 		undoManager->action(this, ss);
4153 	}
4154 	m_softShadowShade = val;
4155 }
4156 
setSoftShadowBlurRadius(double val)4157 void PageItem::setSoftShadowBlurRadius(double val)
4158 {
4159 	if (m_softShadowBlurRadius == val)
4160 		return;
4161 
4162 	if (UndoManager::undoEnabled())
4163 	{
4164 		SimpleState *ss = new SimpleState(Um::SoftShadowBlurRadius, nullptr, Um::IGroup);
4165 		ss->set("SOFT_SHADOW_BLUR_RADIUS");
4166 		ss->set("NEW_VALUE", val);
4167 		ss->set("OLD_VALUE", m_softShadowBlurRadius);
4168 		undoManager->action(this, ss);
4169 	}
4170 	m_softShadowBlurRadius = val;
4171 }
4172 
setSoftShadowXOffset(double val)4173 void PageItem::setSoftShadowXOffset(double val)
4174 {
4175 	if (m_softShadowXOffset == val)
4176 		return;
4177 
4178 	if (UndoManager::undoEnabled())
4179 	{
4180 		SimpleState *ss = new SimpleState(Um::SoftShadowXOffset, nullptr, Um::IGroup);
4181 		ss->set("SOFT_SHADOW_XOFFSET");
4182 		ss->set("NEW_VALUE", val);
4183 		ss->set("OLD_VALUE", m_softShadowXOffset);
4184 		undoManager->action(this, ss);
4185 	}
4186 	m_softShadowXOffset = val;
4187 }
4188 
setSoftShadowYOffset(double val)4189 void PageItem::setSoftShadowYOffset(double val)
4190 {
4191 	if (m_softShadowYOffset == val)
4192 		return;
4193 
4194 	if (UndoManager::undoEnabled())
4195 	{
4196 		SimpleState *ss = new SimpleState(Um::SoftShadowYOffset, nullptr, Um::IGroup);
4197 		ss->set("SOFT_SHADOW_YOFFSET");
4198 		ss->set("NEW_VALUE", val);
4199 		ss->set("OLD_VALUE", m_softShadowYOffset);
4200 		undoManager->action(this, ss);
4201 	}
4202 	m_softShadowYOffset = val;
4203 }
4204 
setSoftShadowOpacity(double val)4205 void PageItem::setSoftShadowOpacity(double val)
4206 {
4207 	if (m_softShadowOpacity == val)
4208 		return;
4209 
4210 	if (UndoManager::undoEnabled())
4211 	{
4212 		SimpleState *ss = new SimpleState(Um::SoftShadowOpacity, nullptr, Um::IGroup);
4213 		ss->set("SOFT_SHADOW_OPACITY");
4214 		ss->set("NEW_VALUE", val);
4215 		ss->set("OLD_VALUE", m_softShadowOpacity);
4216 		undoManager->action(this, ss);
4217 	}
4218 	m_softShadowOpacity = val;
4219 }
4220 
setSoftShadowBlendMode(int val)4221 void PageItem::setSoftShadowBlendMode(int val)
4222 {
4223 	if (m_softShadowBlendMode == val)
4224 		return;
4225 
4226 	if (UndoManager::undoEnabled())
4227 	{
4228 		SimpleState *ss = new SimpleState(Um::SoftShadowBlendMode, nullptr, Um::IGroup);
4229 		ss->set("SOFT_SHADOW_BLEND_MODE");
4230 		ss->set("NEW_VALUE", val);
4231 		ss->set("OLD_VALUE", m_softShadowBlendMode);
4232 		undoManager->action(this, ss);
4233 	}
4234 	m_softShadowBlendMode = val;
4235 }
4236 
setSoftShadowErasedByObject(bool val)4237 void PageItem::setSoftShadowErasedByObject(bool val)
4238 {
4239 	if (m_softShadowErasedByObject == val)
4240 		return;
4241 
4242 	if (UndoManager::undoEnabled())
4243 	{
4244 		SimpleState *ss = new SimpleState(Um::SoftShadowErase, nullptr, Um::IGroup);
4245 		ss->set("SOFT_SHADOW_ERASE");
4246 		ss->set("NEW_VALUE", val);
4247 		ss->set("OLD_VALUE", m_softShadowErasedByObject);
4248 		undoManager->action(this, ss);
4249 	}
4250 	m_softShadowErasedByObject = val;
4251 }
4252 
setSoftShadowHasObjectTransparency(bool val)4253 void PageItem::setSoftShadowHasObjectTransparency(bool val)
4254 {
4255 	if (m_softShadowHasObjectTransparency == val)
4256 		return;
4257 
4258 	if (UndoManager::undoEnabled())
4259 	{
4260 		SimpleState *ss = new SimpleState(Um::SoftShadowObjectTrans, nullptr, Um::IGroup);
4261 		ss->set("SOFT_SHADOW_OBJTRANS");
4262 		ss->set("NEW_VALUE", val);
4263 		ss->set("OLD_VALUE", m_softShadowHasObjectTransparency);
4264 		undoManager->action(this, ss);
4265 	}
4266 	m_softShadowHasObjectTransparency = val;
4267 }
4268 
toggleLock()4269 void PageItem::toggleLock()
4270 {
4271 	if (UndoManager::undoEnabled())
4272 	{
4273 		SimpleState *ss;
4274 		if (m_Locked)
4275 			ss = new SimpleState(Um::UnLock, nullptr, Um::IUnLock);
4276 		else
4277 			ss = new SimpleState(Um::Lock, nullptr, Um::ILock);
4278 		ss->set("LOCK");
4279 		undoManager->action(this, ss);
4280 	}
4281 	m_Locked = !m_Locked;
4282 	//emit frameLocked(m_Locked);
4283 }
4284 
setLocked(bool isLocked)4285 void PageItem::setLocked(bool isLocked)
4286 {
4287 	if (isLocked != m_Locked)
4288 		toggleLock();
4289 }
4290 
getChildren() const4291 QList<PageItem*> PageItem::getChildren() const
4292 {
4293 	QList<PageItem*> ret;
4294 	return ret;
4295 }
4296 
getAllChildren() const4297 QList<PageItem*> PageItem::getAllChildren() const
4298 {
4299 	QList<PageItem*> ret;
4300 	return ret;
4301 }
4302 
toggleSizeLock()4303 void PageItem::toggleSizeLock()
4304 {
4305 	if (UndoManager::undoEnabled())
4306 	{
4307 		SimpleState *ss;
4308 		if (m_SizeLocked)
4309 			ss = new SimpleState(Um::SizeUnLock, nullptr, Um::IUnLock);
4310 		else
4311 			ss = new SimpleState(Um::SizeLock, nullptr, Um::ILock);
4312 		ss->set("SIZE_LOCK");
4313 		undoManager->action(this, ss);
4314 	}
4315 	m_SizeLocked = !m_SizeLocked;
4316 	//emit frameSizeLocked(m_SizeLocked);
4317 }
4318 
setSizeLocked(bool isLocked)4319 void PageItem::setSizeLocked(bool isLocked)
4320 {
4321 	if (isLocked != m_SizeLocked)
4322 		toggleSizeLock();
4323 }
4324 
4325 
setPrintEnabled(bool toPrint)4326 void PageItem::setPrintEnabled(bool toPrint)
4327 {
4328 	if (toPrint != m_PrintEnabled)
4329 		togglePrintEnabled();
4330 }
4331 
togglePrintEnabled()4332 void PageItem::togglePrintEnabled()
4333 {
4334 	if (UndoManager::undoEnabled())
4335 	{
4336 		SimpleState *ss;
4337 		if (m_PrintEnabled)
4338 			ss = new SimpleState(Um::DisablePrint, nullptr, Um::IDisablePrint);
4339 		else
4340 			ss = new SimpleState(Um::EnablePrint, nullptr, Um::IEnablePrint);
4341 		ss->set("PRINT_ENABLED");
4342 		undoManager->action(this, ss);
4343 	}
4344 	m_PrintEnabled=!m_PrintEnabled;
4345 }
4346 
setTextFlowMode(TextFlowMode mode)4347 void PageItem::setTextFlowMode(TextFlowMode mode)
4348 {
4349 	if (m_textFlowMode == mode)
4350 		return;
4351 	if (UndoManager::undoEnabled())
4352 	{
4353 		QString stateMessage;
4354 		if (mode == TextFlowUsesFrameShape)
4355 			stateMessage = Um::ObjectFrame;
4356 		else if (mode == TextFlowUsesBoundingBox)
4357 			stateMessage = Um::BoundingBox;
4358 		else if (mode == TextFlowUsesContourLine)
4359 			stateMessage = Um::ContourLine;
4360 		else if (mode == TextFlowUsesImageClipping)
4361 			stateMessage = Um::ImageClip;
4362 		else
4363 			stateMessage = Um::NoTextFlow;
4364 		SimpleState *ss = new SimpleState(stateMessage, QString(), Um::IFont);
4365 		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
4366 		ss->set("TEXTFLOW_NEWMODE", (int) mode);
4367 		undoManager->action(this, ss);
4368 	}
4369 	m_textFlowMode = mode;
4370 
4371 	checkTextFlowInteractions();
4372 }
4373 
checkTextFlowInteractions(bool allItems)4374 void PageItem::checkTextFlowInteractions(bool allItems)
4375 {
4376 	if (m_Doc->isLoading())
4377 		return;
4378 
4379 	QRectF baseRect(getBoundingRect());
4380 	checkTextFlowInteractions(baseRect, allItems);
4381 }
4382 
checkTextFlowInteractions(const QRectF & baseRect,bool allItems)4383 void PageItem::checkTextFlowInteractions(const QRectF& baseRect, bool allItems)
4384 {
4385 	if (m_Doc->isLoading())
4386 		return;
4387 
4388 	QList<PageItem*>* items = OnMasterPage.isEmpty() ? &m_Doc->DocItems : &m_Doc->MasterItems;
4389 
4390 	int ids = allItems ? items->count() : items->indexOf(this);
4391 	for (int idx = ids - 1; idx >= 0 ; --idx)
4392 	{
4393 		PageItem* item = items->at(idx);
4394 		if (!item->isTextFrame() || (item == this)) // do not bother with no text frames
4395 			continue;
4396 		QRectF uRect(item->getBoundingRect());
4397 		if (baseRect.intersects(uRect))
4398 			item->update();
4399 	}
4400 }
4401 
convertTo(ItemType newType)4402 void PageItem::convertTo(ItemType newType)
4403 {
4404 	if (m_itemType == newType)
4405 		return; // nothing to do -> return
4406 	assert(newType != 1);	//DEBUG CR 2005-02-06
4407 	assert(newType != 3);	//DEBUG CR 2005-02-06
4408 	QString fromType;
4409 	switch (m_itemType)
4410 	{
4411 		case ImageFrame:
4412 			if (isLatexFrame())
4413 				fromType = Um::LatexFrame;
4414 			else
4415 				fromType = Um::ImageFrame;
4416 			break;
4417 		case TextFrame:
4418 			fromType = Um::TextFrame;
4419 			break;
4420 		case Polygon:
4421 		case RegularPolygon:
4422 		case Arc:
4423 			fromType = Um::Polygon;
4424 			break;
4425 		default:
4426 			break;
4427 	}
4428 	QString toType;
4429 	switch (newType)
4430 	{
4431 		case ImageFrame:
4432 			toType = Um::ImageFrame;
4433 			setUPixmap(Um::IImageFrame);
4434 			break;
4435 		case LatexFrame:
4436 			toType = Um::LatexFrame;
4437 			setUPixmap(Um::ILatexFrame);
4438 			break;
4439 		case TextFrame:
4440 			toType = Um::TextFrame;
4441 			setUPixmap(Um::ITextFrame);
4442 			break;
4443 		case Polygon:
4444 		case RegularPolygon:
4445 		case Arc:
4446 			toType = Um::Polygon;
4447 			setUPixmap(Um::IPolygon);
4448 			break;
4449 		case PolyLine:
4450 			toType = Um::Polyline;
4451 			setUPixmap(Um::IPolyline);
4452 			break;
4453 		default:
4454 			setUPixmap(nullptr);
4455 			break;
4456 	}
4457 	/*
4458 	if (UndoManager::undoEnabled())
4459 	{
4460 		SimpleState *ss = new SimpleState(Um::ConvertTo + " " + toType,
4461 										  QString(Um::FromTo).arg(fromType).arg(toType));
4462 		ss->set("CONVERT", "convert");
4463 		ss->set("PAGEITEM", reinterpret_cast<void*>(this));
4464 		ss->set("OLD_TYPE", m_itemType);
4465 		ss->set("NEW_TYPE", newType);
4466 		undoManager->action(this, ss);
4467 	}
4468 	*/
4469 	m_itemType = newType;
4470 	emit frameType(m_itemType);
4471 }
4472 
setLayer(int newLayerID)4473 void PageItem::setLayer(int newLayerID)
4474 {
4475 	if (m_layerID == newLayerID)
4476 		return;
4477 	if (UndoManager::undoEnabled())
4478 	{
4479 		SimpleState *ss = new SimpleState(Um::SendToLayer,
4480 										  QString(Um::FromTo).arg(m_layerID).arg(newLayerID),
4481 										  Um::ILayerAction);
4482 		ss->set("SEND_TO_LAYER");
4483 		ss->set("OLD_LAYER", m_layerID);
4484 		ss->set("NEW_LAYER", newLayerID);
4485 		undoManager->action(this, ss);
4486 	}
4487 	m_layerID = newLayerID;
4488 }
4489 
checkChanges(bool force)4490 void PageItem::checkChanges(bool force)
4491 {
4492 	if (m_Doc->view() == nullptr)
4493 		return;
4494 	bool spreadChanges(false);
4495 
4496 	QRectF textFlowCheckRect;
4497 	if (force || ((textFlowMode() != TextFlowDisabled) && shouldCheck()))
4498 	{
4499 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
4500 			(oldWidth != m_width || oldHeight != m_height) ||
4501 			(oldRot != m_rotation))
4502 		{
4503 			textFlowCheckRect = getOldBoundingRect();
4504 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
4505 			QRectF rect2 = rect1.translated(oldXpos - m_xPos, oldYpos - m_yPos);
4506 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
4507 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
4508 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
4509 		}
4510 	}
4511 
4512 	// has the item been resized
4513 	if (force || ((oldWidth != m_width || oldHeight != m_height) && shouldCheck()))
4514 	{
4515 		resizeUndoAction();
4516 		spreadChanges = (textFlowMode() != TextFlowDisabled);
4517 	}
4518 	// has the item been rotated
4519 	if (force || ((oldRot != m_rotation) && (shouldCheck())))
4520 	{
4521 		rotateUndoAction();
4522 		spreadChanges = (textFlowMode() != TextFlowDisabled);
4523 	}
4524 	// has the item been moved
4525 	if (force || ((oldXpos != m_xPos || oldYpos != m_yPos) && shouldCheck()))
4526 	{
4527 		moveUndoAction();
4528 		spreadChanges = (textFlowMode() != TextFlowDisabled);
4529 	}
4530 	// has the item's image been moved
4531 	if (force || ((oldLocalX != m_imageXOffset || oldLocalY != m_imageYOffset) && shouldCheck()))
4532 		changeImageOffsetUndoAction();
4533 	// has the item's image been scaled
4534 	if (force || ((oldLocalScX != m_imageXScale || oldLocalScY != m_imageYScale) && shouldCheck()))
4535 		changeImageScaleUndoAction();
4536 
4537 	if (spreadChanges)
4538 	{
4539 		checkTextFlowInteractions(textFlowCheckRect);
4540 	}
4541 }
4542 
shouldCheck()4543 bool PageItem::shouldCheck()
4544 {
4545 	return ((!m_Doc->view()->mousePressed()) &&
4546 			(!m_Doc->view()->canvasMode()->arrowKeyDown()) &&
4547 			(!ScCore->primaryMainWindow()->propertiesPalette->userActionOn()));
4548 }
4549 
moveUndoAction()4550 void PageItem::moveUndoAction()
4551 {
4552 	if (oldXpos == m_xPos && oldYpos == m_yPos)
4553 		return;
4554 	if (UndoManager::undoEnabled())
4555 	{
4556 		QString oldp;
4557 		QString newp;
4558 		if (oldOwnPage == -1)
4559 			oldp = Um::ScratchSpace;
4560 		else
4561 			oldp = QString(Um::PageNmbr).arg(m_Doc->FirstPnum + oldOwnPage);
4562 		if (OwnPage == -1)
4563 			newp = Um::ScratchSpace;
4564 		else
4565 			newp = QString(Um::PageNmbr).arg(m_Doc->FirstPnum + OwnPage);
4566 
4567 		QString unitSuffix = unitGetStrFromIndex(m_Doc->unitIndex());
4568 		int unitPrecision  = unitGetPrecisionFromIndex(m_Doc->unitIndex());
4569 		double unitRatio   = m_Doc->unitRatio();
4570 		QString oxString = QString::number(oldXpos * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4571 		QString oyString = QString::number(oldYpos * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4572 		QString nxString = QString::number(m_xPos * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4573 		QString nyString = QString::number(m_yPos * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4574 		QString tooltip  =  QString(Um::MoveFromTo).arg(oxString, oyString, oldp, nxString, nyString, newp);
4575 		SimpleState *ss = new SimpleState(Um::Move, tooltip, Um::IMove);
4576 		ss->set("ITEM_MOVE");
4577 		ss->set("OLD_XPOS", oldXpos);
4578 		ss->set("OLD_YPOS", oldYpos);
4579 		ss->set("NEW_XPOS", m_xPos);
4580 		ss->set("NEW_YPOS", m_yPos);
4581 		undoManager->action(this, ss);
4582 	}
4583 	oldXpos = m_xPos;
4584 	oldYpos = m_yPos;
4585 	oldOwnPage = OwnPage;
4586 }
4587 
resizeUndoAction()4588 void PageItem::resizeUndoAction()
4589 {
4590 	if (oldHeight == m_height && oldWidth == m_width)
4591 		return;
4592 	bool doUndo = true;
4593 	if (isNoteFrame()
4594 		&& ((asNoteFrame()->isAutoHeight() && asNoteFrame()->isAutoWidth())
4595 			|| ((oldHeight == m_height) && asNoteFrame()->isAutoWidth())
4596 			|| ((oldWidth == m_width) && asNoteFrame()->isAutoHeight())))
4597 		doUndo = false;
4598 	if (doUndo && UndoManager::undoEnabled())
4599 	{
4600 		QString unitSuffix = unitGetStrFromIndex(m_Doc->unitIndex());
4601 		int unitPrecision  = unitGetPrecisionFromIndex(m_Doc->unitIndex());
4602 		double unitRatio   = m_Doc->unitRatio();
4603 		QString owString  = QString::number(oldWidth * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4604 		QString ohString  = QString::number(oldHeight * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4605 		QString nwString  = QString::number(m_width * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4606 		QString nhString  = QString::number(m_height * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4607 		QString tooltip   = QString(Um::ResizeFromTo).arg(owString, ohString, nwString, nhString);
4608 		SimpleState *ss = new SimpleState(Um::Resize, tooltip, Um::IResize);
4609 		ss->set("ITEM_RESIZE");
4610 		if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
4611 		{
4612 			ss->set("OLD_WIDTH", oldWidth);
4613 			ss->set("NEW_WIDTH", m_width);
4614 		}
4615 		if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
4616 		{
4617 			ss->set("OLD_HEIGHT", oldHeight);
4618 			ss->set("NEW_HEIGHT", m_height);
4619 		}
4620 		if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
4621 		{
4622 			ss->set("OLD_RXPOS", oldXpos);
4623 			ss->set("OLD_RYPOS", oldYpos);
4624 			ss->set("NEW_RXPOS", m_xPos);
4625 			ss->set("NEW_RYPOS", m_yPos);
4626 		}
4627 		ss->set("OLD_RROT", oldRot);
4628 		ss->set("NEW_RROT", m_rotation);
4629 		undoManager->action(this, ss);
4630 	}
4631 	if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
4632 		oldWidth = m_width;
4633 	if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
4634 		oldHeight = m_height;
4635 	if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
4636 	{
4637 		oldXpos = m_xPos;
4638 		oldYpos = m_yPos;
4639 	}
4640 	oldOwnPage = OwnPage;
4641 	oldRot = m_rotation;
4642 }
4643 
rotateUndoAction()4644 void PageItem::rotateUndoAction()
4645 {
4646 	if (oldRot == m_rotation)
4647 		return;
4648 	if (UndoManager::undoEnabled())
4649 	{
4650 		SimpleState *ss = new SimpleState(Um::Rotate,
4651 										  QString(Um::FromTo).arg(oldRot).arg(m_rotation),
4652 										  Um::IRotate);
4653 		ss->set("ITEM_ROTATE");
4654 		ss->set("OLD_ROT", oldRot);
4655 		ss->set("NEW_ROT", m_rotation);
4656 		if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
4657 		{
4658 			ss->set("OLD_RXPOS", oldXpos);
4659 			ss->set("OLD_RYPOS", oldYpos);
4660 			ss->set("NEW_RXPOS", m_xPos);
4661 			ss->set("NEW_RYPOS", m_yPos);
4662 		}
4663 		if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
4664 		{
4665 			ss->set("OLD_RHEIGHT", oldHeight);
4666 			ss->set("NEW_RHEIGHT", m_height);
4667 		}
4668 		if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
4669 		{
4670 			ss->set("NEW_RWIDTH", m_width);
4671 			ss->set("OLD_RWIDTH", oldWidth);
4672 		}
4673 		undoManager->action(this, ss);
4674 	}
4675 	oldRot = m_rotation;
4676 	oldXpos = m_xPos;
4677 	oldYpos = m_yPos;
4678 	oldOwnPage = OwnPage;
4679 	oldWidth = m_width;
4680 	oldHeight = m_height;
4681 }
4682 
changeImageOffsetUndoAction()4683 void PageItem::changeImageOffsetUndoAction()
4684 {
4685 	if (oldLocalX == m_imageXOffset && oldLocalY == m_imageYOffset)
4686 		return;
4687 	if (UndoManager::undoEnabled())
4688 	{
4689 		QString unitSuffix = unitGetStrFromIndex(m_Doc->unitIndex());
4690 		int unitPrecision  = unitGetPrecisionFromIndex(m_Doc->unitIndex());
4691 		double unitRatio   = m_Doc->unitRatio();
4692 		QString olxString  = QString::number(oldLocalX * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4693 		QString olyString  = QString::number(oldLocalY * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4694 		QString nlxString  = QString::number(m_imageXOffset * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4695 		QString nlyString  = QString::number(m_imageYOffset * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
4696 		QString tooltip   =  QString(Um::ImageOffsetFromTo).arg(olxString, olyString, nlxString, nlyString);
4697 		SimpleState *ss = new SimpleState(Um::ImageOffset, tooltip, Um::IMove);
4698 		ss->set("IMAGE_OFFSET");
4699 		ss->set("OLD_IMAGEXOFFSET", oldLocalX);
4700 		ss->set("OLD_IMAGEYOFFSET", oldLocalY);
4701 		ss->set("NEW_IMAGEXOFFSET", m_imageXOffset);
4702 		ss->set("NEW_IMAGEYOFFSET", m_imageYOffset);
4703 		undoManager->action(this, ss);
4704 	}
4705 	oldLocalX = m_imageXOffset;
4706 	oldLocalY = m_imageYOffset;
4707 }
4708 
changeImageScaleUndoAction()4709 void PageItem::changeImageScaleUndoAction()
4710 {
4711 	if (oldLocalScX == m_imageXScale && oldLocalScY == m_imageYScale)
4712 		return;
4713 	if (UndoManager::undoEnabled())
4714 	{
4715 		SimpleState *ss = new SimpleState(Um::ImageScale,
4716 			QString(Um::ImageScaleFromTo).arg(oldLocalScX).arg(oldLocalScY).arg(m_imageXScale).arg(m_imageYScale), Um::IMove);
4717 		ss->set("IMAGE_SCALE");
4718 		ss->set("OLD_IMAGEXSCALE", oldLocalScX);
4719 		ss->set("OLD_IMAGEYSCALE", oldLocalScY);
4720 		ss->set("NEW_IMAGEXSCALE", m_imageXScale);
4721 		ss->set("NEW_IMAGEYSCALE", m_imageYScale);
4722 		undoManager->action(this, ss);
4723 	}
4724 	oldLocalScX = m_imageXScale;
4725 	oldLocalScY = m_imageYScale;
4726 }
4727 
restore(UndoState * state,bool isUndo)4728 void PageItem::restore(UndoState *state, bool isUndo)
4729 {
4730 	bool SnapGridBackup = m_Doc->SnapGrid;
4731 	bool SnapGuidesBackup = m_Doc->SnapGuides;
4732 	bool SnapElementBackup = m_Doc->SnapElement;
4733 	m_Doc->SnapElement = false;
4734 	m_Doc->SnapGrid = false;
4735 	m_Doc->SnapGuides = false;
4736 	SimpleState *ss = dynamic_cast<SimpleState*>(state);
4737 	bool oldMPMode=m_Doc->masterPageMode();
4738 	m_Doc->setMasterPageMode(!OnMasterPage.isEmpty());
4739 	ScPage *oldCurrentPage = m_Doc->currentPage();
4740 	if (!OnMasterPage.isEmpty())
4741 	{
4742 		oldCurrentPage = m_Doc->currentPage();
4743 		m_Doc->setCurrentPage(m_Doc->MasterPages.at(m_Doc->MasterNames[OnMasterPage]));
4744 	}
4745 	if (ss)
4746 	{
4747 		bool actionFound = checkGradientUndoRedo(ss, isUndo);
4748 		if (!actionFound)
4749 		{
4750 			if (ss->contains("ARC"))
4751 				restoreArc(ss, isUndo);
4752 			else if (ss->contains("MASKTYPE"))
4753 				restoreMaskType(ss, isUndo);
4754 			else if (ss->contains("POLYGON"))
4755 				restorePolygon(ss, isUndo);
4756 			else if (ss->contains("END_ARROWSCALE"))
4757 				restoreEndArrowScale(ss, isUndo);
4758 			else if (ss->contains("START_ARROWSCALE"))
4759 				restoreStartArrowScale(ss, isUndo);
4760 			else if (ss->contains("IMAGE_ROTATION"))
4761 				restoreImageRotation(ss, isUndo);
4762 			else if (ss->contains("ITEM_RESIZE"))
4763 				restoreResize(ss, isUndo);
4764 			else if (ss->contains("ITEM_ROTATE"))
4765 				restoreRotate(ss, isUndo);
4766 			else if (ss->contains("ITEM_MOVE"))
4767 				restoreMove(ss, isUndo);
4768 			else if (ss->contains("FILL"))
4769 				restoreFill(ss, isUndo);
4770 			else if (ss->contains("SHADE"))
4771 				restoreShade(ss, isUndo);
4772 			else if (ss->contains("LINE_COLOR"))
4773 				restoreLineColor(ss, isUndo);
4774 			else if (ss->contains("VERTICAL_ALIGN"))
4775 				restoreVerticalAlign(ss, isUndo);
4776 			else if (ss->contains("COLUMNS"))
4777 				restoreColumns(ss, isUndo);
4778 			else if (ss->contains("COLUMNSGAP"))
4779 				restoreColumnsGap(ss, isUndo);
4780 			else if (ss->contains("LINE_SHADE"))
4781 				restoreLineShade(ss, isUndo);
4782 			else if (ss->contains("DELETE_FRAMETEXT"))
4783 				restoreDeleteFrameText(ss, isUndo);
4784 			else if (ss->contains("DELETE_FRAMEPARA"))
4785 				restoreDeleteFrameParagraph(ss, isUndo);
4786 			else if (ss->contains("INSERT_FRAMETEXT"))
4787 				restoreInsertFrameText(ss, isUndo);
4788 			else if (ss->contains("INSERT_FRAMEPARA"))
4789 				restoreInsertFrameParagraph(ss, isUndo);
4790 			else if (ss->contains("LOREM_FRAMETEXT"))
4791 				restoreInsertFrameText(ss, isUndo);
4792 			else if (ss->contains("APPLY_CHARSTYLE"))
4793 				restoreCharStyle(ss, isUndo);
4794 			else if (ss->contains("SET_CHARSTYLE"))
4795 				restoreSetCharStyle(ss, isUndo);
4796 			else if (ss->contains("SET_PARASTYLE"))
4797 				restoreSetParagraphStyle(ss, isUndo);
4798 			else if (ss->contains("APPLY_PARASTYLE"))
4799 				restoreParagraphStyle(ss, isUndo);
4800 			else if (ss->contains("APPLY_DEFAULTPARASTYLE"))
4801 				restoreDefaultParagraphStyle(ss, isUndo);
4802 			else if (ss->contains("LEFT_TEXTFRAMEDIST"))
4803 				restoreLeftTextFrameDist(ss, isUndo);
4804 			else if (ss->contains("RIGHT_TEXTFRAMEDIST"))
4805 				restoreRightTextFrameDist(ss, isUndo);
4806 			else if (ss->contains("TOP_TEXTFRAMEDIST"))
4807 				restoreTopTextFrameDist(ss, isUndo);
4808 			else if (ss->contains("BOTTOM_TEXTFRAMEDIST"))
4809 				restoreBottomTextFrameDist(ss, isUndo);
4810 			else if (ss->contains("FIRSTLINEOFFSET"))
4811 				restoreFirstLineOffset(ss, isUndo);
4812 			else if (ss->contains("PASTE_PLAINTEXT"))
4813 				restorePastePlainText(ss, isUndo);
4814 			else if (ss->contains("PASTE_TEXT"))
4815 				restorePasteText(ss, isUndo);
4816 			else if (ss->contains("CORNER_RADIUS"))
4817 				restoreCornerRadius(ss, isUndo);
4818 			else if (ss->contains("IMAGEFLIPH"))
4819 				flipImageH();
4820 			else if (ss->contains("IMAGEFLIPV"))
4821 				flipImageV();
4822 			else if (ss->contains("OVERPRINT"))
4823 			{
4824 				if (isUndo)
4825 					doOverprint = !ss->getBool("OVERPRINT");
4826 				else
4827 					doOverprint = ss->getBool("OVERPRINT");
4828 			}
4829 			else if (ss->contains("FILLBLENDMODE"))
4830 			{
4831 				if (isUndo)
4832 					m_fillBlendMode = ss->getInt("FILLBLENDMODE_OLD");
4833 				else
4834 					m_fillBlendMode = ss->getInt("FILLBLENDMODE");
4835 			}
4836 			else if (ss->contains("ACTIONPDFANNOTATION"))
4837 			{
4838 				if (isUndo)
4839 					m_isAnnotation = !ss->getBool("ACTIONPDFANNOTATION");
4840 				else
4841 					m_isAnnotation = ss->getBool("ACTIONPDFANNOTATION");
4842 			}
4843 			else if (ss->contains("ACTIONPDFBOOKMARK"))
4844 			{
4845 				if (isUndo)
4846 					isBookmark = !ss->getBool("ACTIONPDFBOOKMARK");
4847 				else
4848 					isBookmark = ss->getBool("ACTIONPDFBOOKMARK");
4849 			}
4850 			else if (ss->contains("LINEBLENDMODE"))
4851 			{
4852 				if (isUndo)
4853 					m_lineBlendMode = ss->getInt("LINEBLENDMODE_OLD");
4854 				else
4855 					m_lineBlendMode = ss->getInt("LINEBLENDMODE");
4856 			}
4857 			else if (ss->contains("LOCK"))
4858 			{
4859 				select();
4860 				m_Doc->itemSelection_ToggleLock();
4861 			}
4862 			else if (ss->contains("SIZE_LOCK"))
4863 			{
4864 				select();
4865 				m_Doc->itemSelection_ToggleSizeLock();
4866 			}
4867 			else if (ss->contains("PRINT_ENABLED"))
4868 			{
4869 				select();
4870 				m_Doc->itemSelection_TogglePrintEnabled();
4871 			}
4872 			else if (ss->contains("NEW_NAME"))
4873 				restoreName(ss, isUndo);
4874 			else if (ss->contains("SHOW_IMAGE"))
4875 				restoreShowImage(ss, isUndo);
4876 			else if (ss->contains("TRANSPARENCY"))
4877 				restoreFillTP(ss, isUndo);
4878 			else if (ss->contains("LINE_TRANSPARENCY"))
4879 				restoreLineTP(ss, isUndo);
4880 			else if (ss->contains("LINE_STYLE"))
4881 				restoreLineStyle(ss, isUndo);
4882 			else if (ss->contains("LINE_END"))
4883 				restoreLineEnd(ss, isUndo);
4884 			else if (ss->contains("LINE_JOIN"))
4885 				restoreLineJoin(ss, isUndo);
4886 			else if (ss->contains("LINE_WIDTH"))
4887 				restoreLineWidth(ss, isUndo);
4888 			else if (ss->contains("CUSTOM_LINE_STYLE"))
4889 				restoreCustomLineStyle(ss, isUndo);
4890 			else if (ss->contains("START_ARROW"))
4891 				restoreArrow(ss, isUndo, true);
4892 			else if (ss->contains("END_ARROW"))
4893 				restoreArrow(ss, isUndo, false);
4894 			else if (ss->contains("PSTYLE"))
4895 				restorePStyle(ss, isUndo);
4896 			else if (ss->contains("CONVERT"))
4897 				restoreType(ss, isUndo);
4898 			else if (ss->contains("TEXTFLOW_OLDMODE"))
4899 				restoreTextFlowing(ss, isUndo);
4900 			else if (ss->contains("SCALE_MODE"))
4901 				restoreImageScaleMode(ss, isUndo);
4902 			else if (ss->contains("IMAGE_SCALE"))
4903 				restoreImageScaleChange(ss, isUndo);
4904 			else if (ss->contains("IMAGE_OFFSET"))
4905 				restoreImageOffsetChange(ss, isUndo);
4906 			else if (ss->contains("EDIT_CONTOUR"))
4907 				restorePoly(ss, isUndo, true);
4908 			else if (ss->contains("EDIT_SHAPE"))
4909 				restorePoly(ss, isUndo, false);
4910 			else if (ss->contains("RES_TYP"))
4911 				restoreResTyp(ss, isUndo);
4912 			else if (ss->contains("RESET_CONTOUR"))
4913 				restoreContourLine(ss, isUndo);
4914 			else if (ss->contains("CHANGE_SHAPE_TYPE"))
4915 				restoreShapeType(ss, isUndo);
4916 			else if (ss->contains("UNITEITEM"))
4917 				restoreUniteItem(ss, isUndo);
4918 			else if (ss->contains("SPLITITEM"))
4919 				restoreSplitItem(ss, isUndo);
4920 			else if (ss->contains("MIRROR_PATH_H"))
4921 			{
4922 				bool editContour = m_Doc->nodeEdit.isContourLine();
4923 				m_Doc->nodeEdit.setIsContourLine(ss->getBool("IS_CONTOUR"));
4924 				select();
4925 				m_Doc->MirrorPolyH(m_Doc->m_Selection->itemAt(0));
4926 				m_Doc->nodeEdit.setIsContourLine(editContour);
4927 			}
4928 			else if (ss->contains("MIRROR_PATH_V"))
4929 			{
4930 				bool editContour = m_Doc->nodeEdit.isContourLine();
4931 				m_Doc->nodeEdit.setIsContourLine(ss->getBool("IS_CONTOUR"));
4932 				select();
4933 				m_Doc->MirrorPolyV(m_Doc->m_Selection->itemAt(0));
4934 				m_Doc->nodeEdit.setIsContourLine(editContour);
4935 			}
4936 			else if (ss->contains("SEND_TO_LAYER"))
4937 				restoreLayer(ss, isUndo);
4938 			else if (ss->contains("GET_IMAGE"))
4939 				restoreGetImage(ss, isUndo);
4940 			else if (ss->contains("EDIT_SHAPE_OR_CONTOUR"))
4941 				restoreShapeContour(ss, isUndo);
4942 			else if (ss->contains("APPLY_IMAGE_EFFECTS"))
4943 				restoreImageEffects(ss, isUndo);
4944 			else if (ss->contains("DROP_LINKS"))
4945 				restoreDropLinks(ss, isUndo);
4946 			else if (ss->contains("LINK_TEXT_FRAME"))
4947 				restoreLinkTextFrame(ss, isUndo);
4948 			else if (ss->contains("UNLINK_TEXT_FRAME"))
4949 				restoreUnlinkTextFrame(ss, isUndo);
4950 			else if (ss->contains("CLEAR_IMAGE"))
4951 				restoreClearImage(ss, isUndo);
4952 			else if (ss->contains("PASTE_INLINE"))
4953 				restorePasteInline(ss, isUndo);
4954 			else if (ss->contains("TRANSFORM"))
4955 				restoreTransform(ss, isUndo);
4956 			else if (ss->contains("PATH_OPERATION"))
4957 				restorePathOperation(ss, isUndo);
4958 			else if (ss->contains("IMAGE_NBR"))
4959 				restoreImageNbr(ss, isUndo);
4960 			else if (ss->contains("CHANGE_MODE"))
4961 				restoreAppMode(ss, isUndo);
4962 			else if (ss->contains("CONNECT_PATH"))
4963 				restoreConnectPath(ss, isUndo);
4964 			else if (ss->contains("WELD_ITEMS"))
4965 				restoreWeldItems(ss, isUndo);
4966 			else if (ss->contains("UNWELD_ITEM"))
4967 				restoreUnWeldItem(ss, isUndo);
4968 			else if (ss->contains("CLEARMARKSTRING"))
4969 				restoreMarkString(ss, isUndo);
4970 			else if (ss->contains("SOFT_SHADOW"))
4971 				restoreSoftShadow(ss, isUndo);
4972 			else if (ss->contains("SOFT_SHADOW_COLOR"))
4973 				restoreSoftShadowColor(ss, isUndo);
4974 			else if (ss->contains("SOFT_SHADOW_SHADE"))
4975 				restoreSoftShadowShade(ss, isUndo);
4976 			else if (ss->contains("SOFT_SHADOW_BLUR_RADIUS"))
4977 				restoreSoftShadowBlurRadius(ss, isUndo);
4978 			else if (ss->contains("SOFT_SHADOW_XOFFSET"))
4979 				restoreSoftShadowXOffset(ss, isUndo);
4980 			else if (ss->contains("SOFT_SHADOW_YOFFSET"))
4981 				restoreSoftShadowYOffset(ss, isUndo);
4982 			else if (ss->contains("SOFT_SHADOW_OPACITY"))
4983 				restoreSoftShadowOpacity(ss, isUndo);
4984 			else if (ss->contains("SOFT_SHADOW_BLEND_MODE"))
4985 				restoreSoftShadowBlendMode(ss, isUndo);
4986 			else if (ss->contains("SOFT_SHADOW_ERASE"))
4987 				restoreSoftShadowErasedByObject(ss, isUndo);
4988 			else if (ss->contains("SOFT_SHADOW_OBJTRANS"))
4989 				restoreSoftShadowHasObjectTransparency(ss, isUndo);
4990 		}
4991 	}
4992 	if (!OnMasterPage.isEmpty())
4993 		m_Doc->setCurrentPage(oldCurrentPage);
4994 	m_Doc->setMasterPageMode(oldMPMode);
4995 	m_Doc->SnapElement = SnapElementBackup;
4996 	m_Doc->SnapGrid = SnapGridBackup;
4997 	m_Doc->SnapGuides = SnapGuidesBackup;
4998 	if (state->transactionCode == 0 || state->transactionCode == 2)
4999 		this->update();
5000 }
5001 
restoreConnectPath(SimpleState * state,bool isUndo)5002 void PageItem::restoreConnectPath(SimpleState *state, bool isUndo)
5003 {
5004 	ScItemState<QPair<FPointArray, FPointArray> > *is = dynamic_cast<ScItemState<QPair<FPointArray, FPointArray> > *>(state);
5005 	if (isUndo)
5006 	{
5007 		PoLine = is->getItem().first;
5008 		int oldRotMode = m_Doc->rotationMode();
5009 		m_Doc->setRotationMode(0);
5010 		m_Doc->adjustItemSize(this);
5011 		m_Doc->setRotationMode(oldRotMode);
5012 		moveBy(is->getDouble("OLDX") - xPos(),is->getDouble("OLDY") - yPos());
5013 	}
5014 	else
5015 	{
5016 		PoLine = is->getItem().second;
5017 		int oldRotMode = m_Doc->rotationMode();
5018 		m_Doc->setRotationMode(0);
5019 		m_Doc->adjustItemSize(this);
5020 		m_Doc->setRotationMode(oldRotMode);
5021 		moveBy(is->getDouble("NEWX") - xPos(),is->getDouble("NEWY") - yPos());
5022 	}
5023 	OldB2 = width();
5024 	OldH2 = height();
5025 	updateClip();
5026 	ContourLine = PoLine.copy();
5027 }
5028 
restoreUnWeldItem(SimpleState * state,bool isUndo)5029 void PageItem::restoreUnWeldItem(SimpleState *state, bool isUndo)
5030 {
5031 	if (isUndo)
5032 	{
5033 		ScItemState<PageItem*> *is = dynamic_cast<ScItemState<PageItem*>*>(state);
5034 		PageItem* wIt = is->getItem();
5035 		{
5036 			WeldingInfo wInf;
5037 			wInf.weldItem = wIt;
5038 			wInf.weldID = is->getInt("thisID");
5039 			wInf.weldPoint = FPoint(is->getDouble("thisPoint_x"), is->getDouble("thisPoint_y"));
5040 			weldList.append(wInf);
5041 		}
5042 		{
5043 			WeldingInfo wInf;
5044 			wInf.weldItem = this;
5045 			wInf.weldID = is->getInt("ID");
5046 			wInf.weldPoint = FPoint(is->getDouble("Point_x"), is->getDouble("Point_y"));
5047 			wIt->weldList.append(wInf);
5048 		}
5049 	}
5050 	else
5051 	{
5052 		unWeld();
5053 	}
5054 	m_Doc->changed();
5055 	m_Doc->regionsChanged()->update(QRectF());
5056 }
5057 
restoreWeldItems(SimpleState * state,bool isUndo)5058 void PageItem::restoreWeldItems(SimpleState *state, bool isUndo)
5059 {
5060 	if (isUndo)
5061 	{
5062 		unWeld();
5063 	}
5064 	else
5065 	{
5066 		ScItemState<PageItem*> *is = dynamic_cast<ScItemState<PageItem*>*>(state);
5067 		PageItem* wIt = is->getItem();
5068 		weldTo(wIt);
5069 	}
5070 	m_Doc->changed();
5071 	m_Doc->regionsChanged()->update(QRectF());
5072 }
5073 
restoreSoftShadow(SimpleState * state,bool isUndo)5074 void PageItem::restoreSoftShadow(SimpleState *state, bool isUndo)
5075 {
5076 	if (isUndo)
5077 		m_hasSoftShadow = state->getBool("OLD_VALUE");
5078 	else
5079 		m_hasSoftShadow = state->getBool("NEW_VALUE");
5080 	update();
5081 }
5082 
restoreSoftShadowColor(SimpleState * state,bool isUndo)5083 void PageItem::restoreSoftShadowColor(SimpleState *state, bool isUndo)
5084 {
5085 	if (isUndo)
5086 		m_softShadowColor = state->get("OLD_VALUE");
5087 	else
5088 		m_softShadowColor = state->get("NEW_VALUE");
5089 	update();
5090 }
5091 
restoreSoftShadowShade(SimpleState * state,bool isUndo)5092 void PageItem::restoreSoftShadowShade(SimpleState *state, bool isUndo)
5093 {
5094 	if (isUndo)
5095 		m_softShadowShade = state->getInt("OLD_VALUE");
5096 	else
5097 		m_softShadowShade = state->getInt("NEW_VALUE");
5098 	update();
5099 }
5100 
restoreSoftShadowBlurRadius(SimpleState * state,bool isUndo)5101 void PageItem::restoreSoftShadowBlurRadius(SimpleState *state, bool isUndo)
5102 {
5103 	if (isUndo)
5104 		m_softShadowBlurRadius = state->getDouble("OLD_VALUE");
5105 	else
5106 		m_softShadowBlurRadius = state->getDouble("NEW_VALUE");
5107 	update();
5108 }
5109 
restoreSoftShadowXOffset(SimpleState * state,bool isUndo)5110 void PageItem::restoreSoftShadowXOffset(SimpleState *state, bool isUndo)
5111 {
5112 	if (isUndo)
5113 		m_softShadowXOffset = state->getDouble("OLD_VALUE");
5114 	else
5115 		m_softShadowXOffset = state->getDouble("NEW_VALUE");
5116 	update();
5117 }
5118 
restoreSoftShadowYOffset(SimpleState * state,bool isUndo)5119 void PageItem::restoreSoftShadowYOffset(SimpleState *state, bool isUndo)
5120 {
5121 	if (isUndo)
5122 		m_softShadowYOffset = state->getDouble("OLD_VALUE");
5123 	else
5124 		m_softShadowYOffset = state->getDouble("NEW_VALUE");
5125 	update();
5126 }
5127 
restoreSoftShadowOpacity(SimpleState * state,bool isUndo)5128 void PageItem::restoreSoftShadowOpacity(SimpleState *state, bool isUndo)
5129 {
5130 	if (isUndo)
5131 		m_softShadowOpacity = state->getDouble("OLD_VALUE");
5132 	else
5133 		m_softShadowOpacity = state->getDouble("NEW_VALUE");
5134 	update();
5135 }
5136 
restoreSoftShadowErasedByObject(SimpleState * state,bool isUndo)5137 void PageItem::restoreSoftShadowErasedByObject(SimpleState *state, bool isUndo)
5138 {
5139 	if (isUndo)
5140 		m_softShadowErasedByObject = state->getInt("OLD_VALUE");
5141 	else
5142 		m_softShadowErasedByObject = state->getInt("NEW_VALUE");
5143 	update();
5144 }
5145 
restoreSoftShadowHasObjectTransparency(SimpleState * state,bool isUndo)5146 void PageItem::restoreSoftShadowHasObjectTransparency(SimpleState *state, bool isUndo)
5147 {
5148 	if (isUndo)
5149 		m_softShadowHasObjectTransparency = state->getInt("OLD_VALUE");
5150 	else
5151 		m_softShadowHasObjectTransparency = state->getInt("NEW_VALUE");
5152 	update();
5153 }
5154 
restoreSoftShadowBlendMode(SimpleState * state,bool isUndo)5155 void PageItem::restoreSoftShadowBlendMode(SimpleState *state, bool isUndo)
5156 {
5157 	if (isUndo)
5158 		m_softShadowBlendMode = state->getInt("OLD_VALUE");
5159 	else
5160 		m_softShadowBlendMode = state->getInt("NEW_VALUE");
5161 	update();
5162 }
5163 
restoreMarkString(SimpleState * state,bool isUndo)5164 void PageItem::restoreMarkString(SimpleState *state, bool isUndo)
5165 {
5166 	ScItemState< QPair<int,QString> > *is = dynamic_cast<ScItemState< QPair<int,QString> >*>(state);
5167 	if (!is)
5168 		return;
5169 	Mark* mark = itemText.mark(is->getItem().first);
5170 	if (!itemText.hasMark(is->getItem().first))
5171 		return;
5172 	if (isUndo)
5173 		mark->setString(is->getItem().second);
5174 	else
5175 		mark->setString(QString());
5176 }
5177 
checkGradientUndoRedo(SimpleState * ss,bool isUndo)5178 bool PageItem::checkGradientUndoRedo(SimpleState *ss, bool isUndo)
5179 {
5180 	if (ss->contains("SNAP_TO_PATCH"))
5181 	{
5182 		restoreSnapToPatchGrid(ss, isUndo);
5183 		return true;
5184 	}
5185 	if ((ss->contains("UNDO_UPDATE_CONICAL") && isUndo) || (ss->contains("REDO_UPDATE_CONICAL") && !isUndo))
5186 	{
5187 		createConicalMesh();
5188 		return true;
5189 	}
5190 	if (ss->contains("GRAD_COL1"))
5191 	{
5192 		restoreGradientCol1(ss, isUndo);
5193 		return true;
5194 	}
5195 	if (ss->contains("GRAD_COL2"))
5196 	{
5197 		restoreGradientCol2(ss, isUndo);
5198 		return true;
5199 	}
5200 	if (ss->contains("GRAD_COL3"))
5201 	{
5202 		restoreGradientCol3(ss, isUndo);
5203 		return true;
5204 	}
5205 	if (ss->contains("GRAD_COL4"))
5206 	{
5207 		restoreGradientCol4(ss, isUndo);
5208 		return true;
5209 	}
5210 	if (ss->contains("GRAD_POS"))
5211 	{
5212 		restoreGradPos(ss, isUndo);
5213 		return true;
5214 	}
5215 	if (ss->contains("GRAD_QCOLOR1"))
5216 	{
5217 		restoreGradientColor1(ss, isUndo);
5218 		return true;
5219 	}
5220 	if (ss->contains("GRAD_QCOLOR2"))
5221 	{
5222 		restoreGradientColor2(ss, isUndo);
5223 		return true;
5224 	}
5225 	if (ss->contains("GRAD_QCOLOR3"))
5226 	{
5227 		restoreGradientColor3(ss, isUndo);
5228 		return true;
5229 	}
5230 	if (ss->contains("GRAD_QCOLOR4"))
5231 	{
5232 		restoreGradientColor4(ss, isUndo);
5233 		return true;
5234 	}
5235 	if (ss->contains("GRAD_TRANSP1"))
5236 	{
5237 		restoreGradientTrans1(ss, isUndo);
5238 		return true;
5239 	}
5240 	if (ss->contains("GRAD_TRANSP2"))
5241 	{
5242 		restoreGradientTrans2(ss, isUndo);
5243 		return true;
5244 	}
5245 	if (ss->contains("GRAD_TRANSP3"))
5246 	{
5247 		restoreGradientTrans3(ss, isUndo);
5248 		return true;
5249 	}
5250 	if (ss->contains("GRAD_TRANSP4"))
5251 	{
5252 		restoreGradientTrans4(ss, isUndo);
5253 		return true;
5254 	}
5255 	if (ss->contains("GRAD_SHADE1"))
5256 	{
5257 		restoreGradientShade1(ss, isUndo);
5258 		return true;
5259 	}
5260 	if (ss->contains("GRAD_SHADE2"))
5261 	{
5262 		restoreGradientShade2(ss, isUndo);
5263 		return true;
5264 	}
5265 	if (ss->contains("GRAD_SHADE3"))
5266 	{
5267 		restoreGradientShade3(ss, isUndo);
5268 		return true;
5269 	}
5270 	if (ss->contains("GRAD_SHADE4"))
5271 	{
5272 		restoreGradientShade4(ss, isUndo);
5273 		return true;
5274 	}
5275 	if (ss->contains("MOVE_MESH_PATCH"))
5276 	{
5277 		restoreMoveMeshPatch(ss, isUndo);
5278 		return true;
5279 	}
5280 	if (ss->contains("FILL_GRAD"))
5281 	{
5282 		restoreFillGradient(ss, isUndo);
5283 		return true;
5284 	}
5285 	if (ss->contains("MASK_GRAD"))
5286 	{
5287 		restoreMaskGradient(ss, isUndo);
5288 		return true;
5289 	}
5290 	if (ss->contains("STROKE_GRAD"))
5291 	{
5292 		restoreStrokeGradient(ss, isUndo);
5293 		return true;
5294 	}
5295 	if (ss->contains("GRAD_MESH_COLOR"))
5296 	{
5297 		restoreGradientMeshColor(ss, isUndo);
5298 		return true;
5299 	}
5300 	if (ss->contains("GRADSTROKE_START"))
5301 	{
5302 		restoreGradientStrokeStart(ss, isUndo);
5303 		return true;
5304 	}
5305 	if (ss->contains("GRADSTROKE_END"))
5306 	{
5307 		restoreGradientStrokeEnd(ss, isUndo);
5308 		return true;
5309 	}
5310 	if (ss->contains("GRADSTROKE_FOCAL"))
5311 	{
5312 		restoreGradientStrokeFocal(ss, isUndo);
5313 		return true;
5314 	}
5315 	if (ss->contains("GRADSTROKE_SCALE"))
5316 	{
5317 		restoreGradientStrokeScale(ss, isUndo);
5318 		return true;
5319 	}
5320 	if (ss->contains("GRADSTROKE_SKEW"))
5321 	{
5322 		restoreGradientStrokeSkew(ss, isUndo);
5323 		return true;
5324 	}
5325 	if (ss->contains("GRAD_CONTROL1"))
5326 	{
5327 		restoreGradientControl1(ss, isUndo);
5328 		return true;
5329 	}
5330 	if (ss->contains("GRAD_CONTROL2"))
5331 	{
5332 		restoreGradientControl2(ss, isUndo);
5333 		return true;
5334 	}
5335 	if (ss->contains("GRAD_CONTROL3"))
5336 	{
5337 		restoreGradientControl3(ss, isUndo);
5338 		return true;
5339 	}
5340 	if (ss->contains("GRAD_CONTROL4"))
5341 	{
5342 		restoreGradientControl4(ss, isUndo);
5343 		return true;
5344 	}
5345 	if (ss->contains("GRAD_CONTROL5"))
5346 	{
5347 		restoreGradientControl5(ss, isUndo);
5348 		return true;
5349 	}
5350 	if (ss->contains("GRAD_SCALE"))
5351 	{
5352 		restoreGradientScale(ss, isUndo);
5353 		return true;
5354 	}
5355 	if (ss->contains("GRAD_SKEW"))
5356 	{
5357 		restoreGradientSkew(ss, isUndo);
5358 		return true;
5359 	}
5360 	if (ss->contains("GRAD_START"))
5361 	{
5362 		restoreGradientStart(ss, isUndo);
5363 		return true;
5364 	}
5365 	if (ss->contains("GRAD_END"))
5366 	{
5367 		restoreGradientEnd(ss, isUndo);
5368 		return true;
5369 	}
5370 	if (ss->contains("GRAD_FOCAL"))
5371 	{
5372 		restoreGradientFocal(ss, isUndo);
5373 		return true;
5374 	}
5375 	if (ss->contains("GRAD_MASKSCALE"))
5376 	{
5377 		restoreGradientMaskScale(ss, isUndo);
5378 		return true;
5379 	}
5380 	if (ss->contains("GRAD_MASKSKEW"))
5381 	{
5382 		restoreGradientMaskSkew(ss, isUndo);
5383 		return true;
5384 	}
5385 	if (ss->contains("GRAD_MASKSTART"))
5386 	{
5387 		restoreGradientMaskStart(ss, isUndo);
5388 		return true;
5389 	}
5390 	if (ss->contains("GRAD_MASKEND"))
5391 	{
5392 		restoreGradientMaskEnd(ss, isUndo);
5393 		return true;
5394 	}
5395 	if (ss->contains("GRAD_MASKFOCAL"))
5396 	{
5397 		restoreGradientMaskFocal(ss, isUndo);
5398 		return true;
5399 	}
5400 	if (ss->contains("GRAD_TYPE"))
5401 	{
5402 		restoreGradientType(ss, isUndo);
5403 		return true;
5404 	}
5405 	if (ss->contains("GRAD_TYPESTROKE"))
5406 	{
5407 		restoreGradientTypeStroke(ss, isUndo);
5408 		return true;
5409 	}
5410 	if (ss->contains("CREATE_MESH_GRAD"))
5411 	{
5412 		restoreCreateMeshGrad(ss, isUndo);
5413 		return true;
5414 	}
5415 	if (ss->contains("MOVE_MESH_GRAD"))
5416 	{
5417 		restoreMoveMeshGrad(ss, isUndo);
5418 		return true;
5419 	}
5420 	if (ss->contains("RESET_MESH_GRAD"))
5421 	{
5422 		restoreResetMeshGrad(ss, isUndo);
5423 		return true;
5424 	}
5425 	if (ss->contains("REMOVE_MESH_PATCH"))
5426 	{
5427 		restoreRemoveMeshPatch(ss, isUndo);
5428 		return true;
5429 	}
5430 	return false;
5431 }
5432 
restoreAppMode(SimpleState * state,bool isUndo)5433 void PageItem::restoreAppMode(SimpleState *state, bool isUndo)
5434 {
5435 	doc()->m_Selection->clear();
5436 	select();
5437 	if (isUndo)
5438 		doc()->view()->requestMode(state->getInt("OLD"));
5439 	else
5440 		doc()->view()->requestMode(state->getInt("NEW"));
5441 }
5442 
restoreSpiral(SimpleState * ss,bool isUndo)5443 void PageItem::restoreSpiral(SimpleState *ss, bool isUndo)
5444 {
5445 	PageItem_Spiral *item = asSpiral();
5446 	if (isUndo)
5447 	{
5448 		item->spiralStartAngle = ss->getDouble("OLD_START");
5449 		item->spiralEndAngle = ss->getDouble("OLD_END");
5450 		item->spiralFactor = ss->getDouble("OLD_FACTOR");
5451 	}
5452 	else
5453 	{
5454 		item->spiralStartAngle = ss->getDouble("NEW_START");
5455 		item->spiralEndAngle = ss->getDouble("NEW_END");
5456 		item->spiralFactor = ss->getDouble("NEW_FACTOR");
5457 	}
5458 	item->recalcPath();
5459 	update();
5460 	doc()->changed();
5461 }
5462 
restorePolygon(SimpleState * ss,bool isUndo)5463 void PageItem::restorePolygon(SimpleState *ss, bool isUndo)
5464 {
5465 	PageItem_RegularPolygon *item = asRegularPolygon();
5466 	if (isUndo)
5467 	{
5468 		item->polyCorners = ss->getInt("OLD_CORNER");
5469 		item->polyUseFactor = ss->getBool("OLD_USEFACTOR");
5470 		item->polyFactor = ss->getDouble("OLD_FACTOR");
5471 		item->polyRotation = ss->getDouble("OLD_ROTATION");
5472 		item->polyCurvature = ss->getDouble("OLD_CURV");
5473 		item->polyInnerRot = ss->getDouble("OLD_INNER");
5474 		item->polyOuterCurvature = ss->getDouble("OLD_OUTER");
5475 	}
5476 	else
5477 	{
5478 		item->polyCorners = ss->getInt("NEW_CORNER");
5479 		item->polyUseFactor = ss->getBool("NEW_USEFACTOR");
5480 		item->polyFactor = ss->getDouble("NEW_FACTOR");
5481 		item->polyRotation = ss->getDouble("NEW_ROTATION");
5482 		item->polyCurvature = ss->getDouble("NEW_CURV");
5483 		item->polyInnerRot = ss->getDouble("NEW_INNER");
5484 		item->polyOuterCurvature = ss->getDouble("NEW_OUTER");
5485 	}
5486 	item->recalcPath();
5487 	update();
5488 	doc()->changed();
5489 }
5490 
restoreArc(SimpleState * state,bool isUndo)5491 void PageItem::restoreArc(SimpleState *state, bool isUndo)
5492 {
5493 	ScItemState<QPair<FPointArray, FPointArray> > *ss = dynamic_cast<ScItemState<QPair<FPointArray, FPointArray> > *>(state);
5494 	if (!ss)
5495 		qFatal("PageItem::restoreArc: dynamic cast failed");
5496 	PageItem_Arc *item = asArc();
5497 	if (isUndo)
5498 	{
5499 		item->arcHeight = ss->getDouble("OLD_HEIGHT");
5500 		item->arcWidth = ss->getDouble("OLD_WIDTH");
5501 		item->arcStartAngle = ss->getDouble("OLD_START");
5502 		item->arcSweepAngle = ss->getDouble("OLD_SWEEP");
5503 		item->PoLine = ss->getItem().first;
5504 		doc()->adjustItemSize(item);
5505 		moveBy(ss->getDouble("OLD_XPOS") - xPos(),ss->getDouble("OLD_YPOS") - yPos());
5506 	}
5507 	else
5508 	{
5509 		item->arcHeight = ss->getDouble("NEW_HEIGHT");
5510 		item->arcWidth = ss->getDouble("NEW_WIDTH");
5511 		item->arcStartAngle = ss->getDouble("NEW_START");
5512 		item->arcSweepAngle = ss->getDouble("NEW_SWEEP");
5513 		item->PoLine = ss->getItem().second;
5514 		doc()->adjustItemSize(item);
5515 		moveBy(ss->getDouble("NEW_XPOS") - xPos(),ss->getDouble("NEW_YPOS") - yPos());
5516 	}
5517 	update();
5518 	//doc()->changed();
5519 }
5520 
restoreImageNbr(SimpleState * state,bool isUndo)5521 void PageItem::restoreImageNbr(SimpleState *state, bool isUndo)
5522 {
5523 	if (isUndo)
5524 		pixm.imgInfo.actualPageNumber = state->getInt("OLD");
5525 	else
5526 		pixm.imgInfo.actualPageNumber = state->getInt("NEW");
5527 	loadImage(externalFile(), true);
5528 	update();
5529 }
5530 
restoreTransform(SimpleState * ss,bool isUndo)5531 void PageItem::restoreTransform(SimpleState *ss, bool isUndo)
5532 {
5533 	ScItemState<QList<QTransform> > *is = dynamic_cast<ScItemState<QList<QTransform > >*>(ss);
5534 	if (!is)
5535 		qFatal("PageItem::restoreTransform: dynamic cast failed");
5536 	int x = is->getDouble("DX");
5537 	int y = is->getDouble("DY");
5538 	if (isUndo)
5539 	{
5540 		PoLine.translate(x,y);
5541 		PoLine.map(is->getItem().at(2).inverted());
5542 		PoLine.map(is->getItem().at(1).inverted());
5543 		PoLine.map(is->getItem().at(0).inverted());
5544 		PoLine.translate(-x,-y);
5545 		ContourLine.translate(x,y);
5546 		ContourLine.map(is->getItem().at(2).inverted());
5547 		ContourLine.map(is->getItem().at(1).inverted());
5548 		ContourLine.map(is->getItem().at(0).inverted());
5549 		ContourLine.translate(-x,-y);
5550 		doc()->adjustItemSize(this);
5551 		moveBy(is->getDouble("POSX") - xPos(),is->getDouble("POSY") - yPos());
5552 	}
5553 	else
5554 	{
5555 		PoLine.translate(x,y);
5556 		PoLine.map(is->getItem().at(0));
5557 		PoLine.map(is->getItem().at(1));
5558 		PoLine.map(is->getItem().at(2));
5559 		PoLine.translate(-x,-y);
5560 		ContourLine.translate(x,y);
5561 		ContourLine.map(is->getItem().at(0));
5562 		ContourLine.map(is->getItem().at(1));
5563 		ContourLine.map(is->getItem().at(2));
5564 		ContourLine.translate(-x,-y);
5565 		doc()->adjustItemSize(this);
5566 	}
5567 }
5568 
restoreSnapToPatchGrid(SimpleState * state,bool isUndo)5569 void PageItem::restoreSnapToPatchGrid(SimpleState *state, bool isUndo)
5570 {
5571 	if (isUndo)
5572 		snapToPatchGrid = state->getBool("OLD");
5573 	else
5574 		snapToPatchGrid = !state->getBool("OLD");
5575 	update();
5576 }
5577 
5578 
restoreMaskType(SimpleState * state,bool isUndo)5579 void PageItem::restoreMaskType(SimpleState *state, bool isUndo)
5580 {
5581 	if (isUndo)
5582 		GrMask = state->getInt("OLD");
5583 	else
5584 		GrMask = state->getInt("NEW");
5585 	update();
5586 }
5587 
restoreGradientCol1(SimpleState * state,bool isUndo)5588 void PageItem::restoreGradientCol1(SimpleState *state, bool isUndo)
5589 {
5590 	if (isUndo)
5591 		GrColorP1 = state->get("OLD");
5592 	else
5593 		GrColorP1 = state->get("NEW");
5594 	update();
5595 }
5596 
restoreGradientCol2(SimpleState * state,bool isUndo)5597 void PageItem::restoreGradientCol2(SimpleState *state, bool isUndo)
5598 {
5599 	if (isUndo)
5600 		GrColorP2 = state->get("OLD");
5601 	else
5602 		GrColorP2 = state->get("NEW");
5603 	update();
5604 }
5605 
restoreGradientCol3(SimpleState * state,bool isUndo)5606 void PageItem::restoreGradientCol3(SimpleState *state, bool isUndo)
5607 {
5608 	if (isUndo)
5609 		GrColorP3 = state->get("OLD");
5610 	else
5611 		GrColorP3 = state->get("NEW");
5612 	update();
5613 }
5614 
restoreGradientCol4(SimpleState * state,bool isUndo)5615 void PageItem::restoreGradientCol4(SimpleState *state, bool isUndo)
5616 {
5617 	if (isUndo)
5618 		GrColorP4 = state->get("OLD");
5619 	else
5620 		GrColorP4 = state->get("NEW");
5621 	update();
5622 }
5623 
restoreGradientShade1(SimpleState * state,bool isUndo)5624 void PageItem::restoreGradientShade1(SimpleState *state, bool isUndo)
5625 {
5626 	if (isUndo)
5627 		GrCol1Shade = state->getInt("OLD");
5628 	else
5629 		GrCol1Shade = state->getInt("NEW");
5630 	update();
5631 }
5632 
restoreGradientShade2(SimpleState * state,bool isUndo)5633 void PageItem::restoreGradientShade2(SimpleState *state, bool isUndo)
5634 {
5635 	if (isUndo)
5636 		GrCol2Shade = state->getInt("OLD");
5637 	else
5638 		GrCol2Shade = state->getInt("NEW");
5639 	update();
5640 }
5641 
restoreGradientShade3(SimpleState * state,bool isUndo)5642 void PageItem::restoreGradientShade3(SimpleState *state, bool isUndo)
5643 {
5644 	if (isUndo)
5645 		GrCol3Shade = state->getInt("OLD");
5646 	else
5647 		GrCol3Shade = state->getInt("NEW");
5648 	update();
5649 }
5650 
restoreGradientShade4(SimpleState * state,bool isUndo)5651 void PageItem::restoreGradientShade4(SimpleState *state, bool isUndo)
5652 {
5653 	if (isUndo)
5654 		GrCol4Shade = state->getInt("OLD");
5655 	else
5656 		GrCol4Shade = state->getInt("NEW");
5657 	update();
5658 }
5659 
restoreGradientTrans1(SimpleState * state,bool isUndo)5660 void PageItem::restoreGradientTrans1(SimpleState *state, bool isUndo)
5661 {
5662 	if (isUndo)
5663 		GrCol1transp = state->getDouble("OLD");
5664 	else
5665 		GrCol1transp = state->getDouble("NEW");
5666 	update();
5667 }
5668 
restoreGradientTrans2(SimpleState * state,bool isUndo)5669 void PageItem::restoreGradientTrans2(SimpleState *state, bool isUndo)
5670 {
5671 	if (isUndo)
5672 		GrCol2transp = state->getDouble("OLD");
5673 	else
5674 		GrCol2transp = state->getDouble("NEW");
5675 	update();
5676 }
5677 
restoreGradientTrans3(SimpleState * state,bool isUndo)5678 void PageItem::restoreGradientTrans3(SimpleState *state, bool isUndo)
5679 {
5680 	if (isUndo)
5681 		GrCol3transp = state->getDouble("OLD");
5682 	else
5683 		GrCol3transp = state->getDouble("NEW");
5684 	update();
5685 }
5686 
restoreGradientTrans4(SimpleState * state,bool isUndo)5687 void PageItem::restoreGradientTrans4(SimpleState *state, bool isUndo)
5688 {
5689 	if (isUndo)
5690 		GrCol4transp = state->getDouble("OLD");
5691 	else
5692 		GrCol4transp = state->getDouble("NEW");
5693 	update();
5694 }
5695 
restoreGradPos(SimpleState * state,bool isUndo)5696 void PageItem::restoreGradPos(SimpleState *state, bool isUndo)
5697 {
5698 	ScItemState<QList<FPoint> > *is = dynamic_cast<ScItemState<QList<FPoint> > *>(state);
5699 	if (!is)
5700 		qFatal("PageItem::restoreGradPos: dynamic cast failed");
5701 	if (isUndo)
5702 	{
5703 		GrStartX = is->getDouble("OLDSTARTX");
5704 		GrStartY = is->getDouble("OLDSTARTY");
5705 		GrEndX = is->getDouble("OLDENDX");
5706 		GrEndY = is->getDouble("OLDENDY");
5707 		GrFocalX = is->getDouble("OLDFOCALX");
5708 		GrFocalY = is->getDouble("OLDFOCALY");
5709 		GrScale = is->getDouble("OLDSCALE");
5710 		GrSkew = is->getDouble("OLDSKEW");
5711 		GrControl1 = is->getItem().at(0);
5712 		GrControl2 = is->getItem().at(2);
5713 		GrControl3 = is->getItem().at(4);
5714 		GrControl4 = is->getItem().at(6);
5715 		GrControl5 = is->getItem().at(8);
5716 		GrStrokeStartX = is->getDouble("OLDSTROKESTARTX");
5717 		GrStrokeStartY = is->getDouble("OLDSTROKESTARTY");
5718 		GrStrokeEndX = is->getDouble("OLDSTROKEENDX");
5719 		GrStrokeEndY = is->getDouble("OLDSTROKEENDY");
5720 		GrStrokeFocalX = is->getDouble("OLDSTROKEFOCALX");
5721 		GrStrokeFocalY = is->getDouble("OLDSTROKEFOCALY");
5722 		GrStrokeScale = is->getDouble("OLDSTROKESCALE");
5723 		GrStrokeSkew = is->getDouble("OLDSTROKESKEW");
5724 		GrMaskStartX = is->getDouble("OLDMARKSTARTX");
5725 		GrMaskStartY = is->getDouble("OLDMARKSTARTY");
5726 		GrMaskEndX = is->getDouble("OLDMARKENDX");
5727 		GrMaskEndY = is->getDouble("OLDMARKENDY");
5728 		GrMaskFocalX = is->getDouble("OLDMARKFOCALX");
5729 		GrMaskFocalY = is->getDouble("OLDMARKFOCALY");
5730 		GrMaskScale = is->getDouble("OLDMARKSCALE");
5731 		GrMaskSkew = is->getDouble("OLDMARKSKEW");
5732 	}
5733 	else
5734 	{
5735 		GrStartX = is->getDouble("STARTX");
5736 		GrStartY = is->getDouble("STARTY");
5737 		GrEndX = is->getDouble("ENDX");
5738 		GrEndY = is->getDouble("ENDY");
5739 		GrFocalX = is->getDouble("FOCALX");
5740 		GrFocalY = is->getDouble("FOCALY");
5741 		GrScale = is->getDouble("SCALE");
5742 		GrSkew = is->getDouble("SKEW");
5743 		GrControl1 = is->getItem().at(1);
5744 		GrControl2 = is->getItem().at(3);
5745 		GrControl3 = is->getItem().at(5);
5746 		GrControl4 = is->getItem().at(7);
5747 		GrControl5 = is->getItem().at(9);
5748 		GrStrokeStartX = is->getDouble("STROKESTARTX");
5749 		GrStrokeStartY = is->getDouble("STROKESTARTY");
5750 		GrStrokeEndX = is->getDouble("STROKEENDX");
5751 		GrStrokeEndY = is->getDouble("STROKEENDY");
5752 		GrStrokeFocalX = is->getDouble("STROKEFOCALX");
5753 		GrStrokeFocalY = is->getDouble("STROKEFOCALY");
5754 		GrStrokeScale = is->getDouble("STROKESCALE");
5755 		GrStrokeSkew = is->getDouble("STROKESKEW");
5756 		GrMaskStartX = is->getDouble("MARKSTARTX");
5757 		GrMaskStartY = is->getDouble("MARKSTARTY");
5758 		GrMaskEndX = is->getDouble("MARKENDX");
5759 		GrMaskEndY = is->getDouble("MARKENDY");
5760 		GrMaskFocalX = is->getDouble("MARKFOCALX");
5761 		GrMaskFocalY = is->getDouble("MARKFOCALY");
5762 		GrMaskScale = is->getDouble("MARKSCALE");
5763 		GrMaskSkew = is->getDouble("MARKSKEW");
5764 	}
5765 	if (GrType == Gradient_Conical)
5766 		createConicalMesh();
5767 	update();
5768 }
5769 
restoreGradientColor1(SimpleState * state,bool isUndo)5770 void PageItem::restoreGradientColor1(SimpleState *state, bool isUndo)
5771 {
5772 	ScItemState<QPair<QColor,QColor> > *is = dynamic_cast<ScItemState<QPair<QColor,QColor> > *>(state);
5773 	if (!is)
5774 		qFatal("PageItem::restoreGradientColor1: dynamic cast failed");
5775 	if (isUndo)
5776 		m_grQColorP1 = is->getItem().first;
5777 	else
5778 		m_grQColorP1 = is->getItem().second;
5779 	update();
5780 }
5781 
restoreRemoveMeshPatch(SimpleState * state,bool isUndo)5782 void PageItem::restoreRemoveMeshPatch(SimpleState *state, bool isUndo)
5783 {
5784 	ScItemState<meshGradientPatch>* is = dynamic_cast<ScItemState<meshGradientPatch> *>(state);
5785 	if (!is)
5786 		qFatal("PageItem::restoreRemoveMeshPatch: dynamic cast failed");
5787 	if (isUndo)
5788 	{
5789 		selectedMeshPointX = is->getInt("POS");
5790 		meshGradientPatches.insert(selectedMeshPointX,is->getItem());
5791 	}
5792 	else
5793 	{
5794 		meshGradientPatches.removeAt(selectedMeshPointX);
5795 		selectedMeshPointX = -1;
5796 	}
5797 	update();
5798 }
5799 
restoreCreateMeshGrad(SimpleState * state,bool isUndo)5800 void PageItem::restoreCreateMeshGrad(SimpleState *state, bool isUndo)
5801 {
5802 	ScItemState<QList<QList<MeshPoint> > >* is = dynamic_cast<ScItemState<QList<QList<MeshPoint> > > *>(state);
5803 	if (!is)
5804 		qFatal("PageItem::restoreCreateMeshGrad: dynamic cast failed");
5805 	if (isUndo)
5806 		meshGradientArray = is->getItem();
5807 	else
5808 		createGradientMesh(is->getInt("ROW"), is->getInt("COL"));
5809 	update();
5810 }
5811 
restoreMoveMeshGrad(SimpleState * state,bool isUndo)5812 void PageItem::restoreMoveMeshGrad(SimpleState *state, bool isUndo)
5813 {
5814 	ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> > *is = dynamic_cast<ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> > *>(state);
5815 	if (!is)
5816 		qFatal("PageItem::restoreMoveMeshGrad: dynamic cast failed");
5817 	if (isUndo)
5818 	{
5819 		PoLine = is->getItem().second;
5820 		ClipEdited = true;
5821 		FrameType = is->getInt("FRAME_TYPE");
5822 		FPoint wh = getMaxClipF(&PoLine);
5823 		setWidthHeight(wh.x(),wh.y());
5824 		m_Doc->adjustItemSize(this);
5825 		OldB2 = is->getInt("OLDB");
5826 		OldH2 = is->getInt("OLDH");
5827 		updateClip();
5828 		meshGradientArray = is->getItem().first;
5829 	}
5830 	else
5831 		meshToShape();
5832 	update();
5833 }
5834 
restoreResetMeshGrad(SimpleState * state,bool isUndo)5835 void PageItem::restoreResetMeshGrad(SimpleState *state, bool isUndo)
5836 {
5837 	ScItemState<QList<QList<MeshPoint> > > *is = dynamic_cast<ScItemState<QList<QList<MeshPoint> > > *>(state);
5838 	if (!is)
5839 		qFatal("PageItem::restoreResetMeshGrad: dynamic cast failed");
5840 	if (isUndo)
5841 		meshGradientArray = is->getItem();
5842 	else
5843 		resetGradientMesh();
5844 	update();
5845 }
5846 
restoreGradientColor2(SimpleState * state,bool isUndo)5847 void PageItem::restoreGradientColor2(SimpleState *state, bool isUndo)
5848 {
5849 	ScItemState<QPair<QColor,QColor> > *is = dynamic_cast<ScItemState<QPair<QColor,QColor> > *>(state);
5850 	if (!is)
5851 		qFatal("PageItem::restoreGradientColor2: dynamic cast failed");
5852 	if (isUndo)
5853 		m_grQColorP2 = is->getItem().first;
5854 	else
5855 		m_grQColorP2 = is->getItem().second;
5856 	update();
5857 }
5858 
restoreGradientColor3(SimpleState * state,bool isUndo)5859 void PageItem::restoreGradientColor3(SimpleState *state, bool isUndo)
5860 {
5861 	ScItemState<QPair<QColor,QColor> > *is = dynamic_cast<ScItemState<QPair<QColor,QColor> > *>(state);
5862 	if (!is)
5863 		qFatal("PageItem::restoreGradientColor3: dynamic cast failed");
5864 	if (isUndo)
5865 		m_grQColorP3 = is->getItem().first;
5866 	else
5867 		m_grQColorP3 = is->getItem().second;
5868 	update();
5869 }
5870 
restoreGradientColor4(SimpleState * state,bool isUndo)5871 void PageItem::restoreGradientColor4(SimpleState *state, bool isUndo)
5872 {
5873 	ScItemState<QPair<QColor,QColor> > *is = dynamic_cast<ScItemState<QPair<QColor,QColor> > *>(state);
5874 	if (!is)
5875 		qFatal("PageItem::restoreGradientColor4: dynamic cast failed");
5876 	if (isUndo)
5877 		m_grQColorP4 = is->getItem().first;
5878 	else
5879 		m_grQColorP4 = is->getItem().second;
5880 	update();
5881 }
5882 
restoreMoveMeshPatch(SimpleState * state,bool isUndo)5883 void PageItem::restoreMoveMeshPatch(SimpleState *state, bool isUndo)
5884 {
5885 	ScItemState<QPair<MeshPoint,MeshPoint> > *is = dynamic_cast<ScItemState<QPair<MeshPoint,MeshPoint> > *>(state);
5886 	if (!is)
5887 		qFatal("PageItem::restoreMoveMeshPatch: dynamic cast failed");
5888 	int x = is->getInt("X");
5889 	int y = is->getInt("Y");
5890 	if (isUndo)
5891 	{
5892 		if (is->getBool("ARRAY"))
5893 			meshGradientArray[x][y] = is->getItem().first;
5894 		else
5895 			switch (y)
5896 			{
5897 				case 1:
5898 					meshGradientPatches[x].TL = is->getItem().first;
5899 					break;
5900 				case 2:
5901 					meshGradientPatches[x].TR = is->getItem().first;
5902 					break;
5903 				case 3:
5904 					meshGradientPatches[x].BR = is->getItem().first;
5905 					break;
5906 				case 4:
5907 					meshGradientPatches[x].BL = is->getItem().first;
5908 					break;
5909 			}
5910 	}
5911 	else
5912 	{
5913 		if (is->getBool("ARRAY"))
5914 			meshGradientArray[x][y] = is->getItem().second;
5915 		else
5916 			switch (y)
5917 			{
5918 				case 1:
5919 					meshGradientPatches[x].TL = is->getItem().second;
5920 					break;
5921 				case 2:
5922 					meshGradientPatches[x].TR = is->getItem().second;
5923 					break;
5924 				case 3:
5925 					meshGradientPatches[x].BR = is->getItem().second;
5926 					break;
5927 				case 4:
5928 					meshGradientPatches[x].BL = is->getItem().second;
5929 					break;
5930 			}
5931 	}
5932 	update();
5933 }
5934 
restoreFillGradient(SimpleState * state,bool isUndo)5935 void PageItem::restoreFillGradient(SimpleState *state, bool isUndo)
5936 {
5937 	ScItemState<QPair<VGradient,VGradient> > *is = dynamic_cast<ScItemState<QPair<VGradient,VGradient> > *>(state);
5938 	if (!is)
5939 		qFatal("PageItem::restoreFillGradient: dynamic cast failed");
5940 	if (isUndo)
5941 		fill_gradient = is->getItem().first;
5942 	else
5943 		fill_gradient = is->getItem().second;
5944 	if (gradientType() == 13)
5945 		createConicalMesh();
5946 	update();
5947 }
5948 
restoreMaskGradient(SimpleState * state,bool isUndo)5949 void PageItem::restoreMaskGradient(SimpleState *state, bool isUndo)
5950 {
5951 	ScItemState<QPair<VGradient,VGradient> > *is = dynamic_cast<ScItemState<QPair<VGradient,VGradient> > *>(state);
5952 	if (!is)
5953 		qFatal("PageItem::restoreMaskGradient: dynamic cast failed");
5954 	if (isUndo)
5955 		mask_gradient = is->getItem().first;
5956 	else
5957 		mask_gradient = is->getItem().second;
5958 	update();
5959 }
5960 
5961 
restoreStrokeGradient(SimpleState * state,bool isUndo)5962 void PageItem::restoreStrokeGradient(SimpleState *state, bool isUndo)
5963 {
5964 	ScItemState<QPair<VGradient,VGradient> > *is = dynamic_cast<ScItemState<QPair<VGradient,VGradient> > *>(state);
5965 	if (!is)
5966 		qFatal("PageItem::restoreStrokeGradient: dynamic cast failed");
5967 	if (isUndo)
5968 		stroke_gradient = is->getItem().first;
5969 	else
5970 		stroke_gradient = is->getItem().second;
5971 	update();
5972 }
5973 
restoreGradientMeshColor(SimpleState * ss,bool isUndo)5974 void PageItem::restoreGradientMeshColor(SimpleState *ss, bool isUndo)
5975 {
5976 	ScItemState<QPair<QColor,QColor> > *is = dynamic_cast<ScItemState<QPair<QColor,QColor> > *>(ss);
5977 	if (!is)
5978 		qFatal("PageItem::restoreGradientMeshColor: dynamic cast failed");
5979 	int x = is->getInt("X");
5980 	int y = is->getInt("Y");
5981 	MeshPoint *mp=nullptr;
5982 	if (is->getBool("PATCH"))
5983 	{
5984 		meshGradientPatch *patch = &meshGradientPatches[x];
5985 		switch (y)
5986 		{
5987 			case 1:
5988 				mp = &(patch->TL);
5989 				break;
5990 			case 2:
5991 				mp = &(patch->TR);
5992 				break;
5993 			case 3:
5994 				mp = &(patch->BR);
5995 				break;
5996 			case 4:
5997 				mp = &(patch->BL);
5998 				break;
5999 		}
6000 	}
6001 	else
6002 		mp = &meshGradientArray[x][y];
6003 	if (mp == nullptr)
6004 		qFatal("PageItem::restoreGradientMeshColor: mp is a nullptr");
6005 	if (isUndo)
6006 	{
6007 		mp->colorName = is->get("OLD_COLOR_NAME");
6008 		mp->color = is->getItem().first;
6009 		mp->shade = is->getInt("OLD_SHADE");
6010 		mp->transparency = is->getDouble("OLD_TRANS");
6011 	}
6012 	else
6013 	{
6014 		mp->colorName = is->get("NEW_COLOR_NAME");
6015 		mp->color = is->getItem().second;
6016 		mp->shade = is->getInt("NEW_SHADE");
6017 		mp->transparency = is->getDouble("NEW_TRANS");
6018 	}
6019 }
6020 
restoreGradientStart(SimpleState * is,bool isUndo)6021 void PageItem::restoreGradientStart(SimpleState *is, bool isUndo)
6022 {
6023 	if (isUndo)
6024 	{
6025 		GrStartX = is->getDouble("OLDX");
6026 		GrStartY = is->getDouble("OLDY");
6027 	}
6028 	else
6029 	{
6030 		GrStartX = is->getDouble("NEWX");
6031 		GrStartY = is->getDouble("NEWY");
6032 	}
6033 }
6034 
restoreGradientEnd(SimpleState * is,bool isUndo)6035 void PageItem::restoreGradientEnd(SimpleState *is, bool isUndo)
6036 {
6037 	if (isUndo)
6038 	{
6039 		GrEndX = is->getDouble("OLDX");
6040 		GrEndY = is->getDouble("OLDY");
6041 	}
6042 	else
6043 	{
6044 		GrEndX = is->getDouble("NEWX");
6045 		GrEndY = is->getDouble("NEWY");
6046 	}
6047 }
6048 
restoreGradientFocal(SimpleState * is,bool isUndo)6049 void PageItem::restoreGradientFocal(SimpleState *is, bool isUndo)
6050 {
6051 	if (isUndo)
6052 	{
6053 		GrFocalX = is->getDouble("OLDX");
6054 		GrFocalY = is->getDouble("OLDY");
6055 	}
6056 	else
6057 	{
6058 		GrFocalX = is->getDouble("NEWX");
6059 		GrFocalY = is->getDouble("NEWY");
6060 	}
6061 }
6062 
restoreGradientScale(SimpleState * is,bool isUndo)6063 void PageItem::restoreGradientScale(SimpleState *is, bool isUndo)
6064 {
6065 	if (isUndo)
6066 		GrScale= is->getDouble("OLD");
6067 	else
6068 		GrScale = is->getDouble("NEW");
6069 }
6070 
restoreGradientSkew(SimpleState * is,bool isUndo)6071 void PageItem::restoreGradientSkew(SimpleState *is, bool isUndo)
6072 {
6073 	if (isUndo)
6074 		GrSkew = is->getDouble("OLD");
6075 	else
6076 		GrSkew = is->getDouble("NEW");
6077 }
6078 
restoreGradientMaskStart(SimpleState * is,bool isUndo)6079 void PageItem::restoreGradientMaskStart(SimpleState *is, bool isUndo)
6080 {
6081 	if (isUndo)
6082 	{
6083 		GrMaskStartX = is->getDouble("OLDX");
6084 		GrMaskStartY = is->getDouble("OLDY");
6085 	}
6086 	else
6087 	{
6088 		GrMaskStartX = is->getDouble("NEWX");
6089 		GrMaskStartY = is->getDouble("NEWY");
6090 	}
6091 }
6092 
restoreGradientMaskEnd(SimpleState * is,bool isUndo)6093 void PageItem::restoreGradientMaskEnd(SimpleState *is, bool isUndo)
6094 {
6095 	if (isUndo)
6096 	{
6097 		GrMaskEndX = is->getDouble("OLDX");
6098 		GrMaskEndY = is->getDouble("OLDY");
6099 	}
6100 	else
6101 	{
6102 		GrMaskEndX = is->getDouble("NEWX");
6103 		GrMaskEndY = is->getDouble("NEWY");
6104 	}
6105 }
6106 
restoreGradientMaskFocal(SimpleState * is,bool isUndo)6107 void PageItem::restoreGradientMaskFocal(SimpleState *is, bool isUndo)
6108 {
6109 	if (isUndo)
6110 	{
6111 		GrMaskFocalX = is->getDouble("OLDX");
6112 		GrMaskFocalY = is->getDouble("OLDY");
6113 	}
6114 	else
6115 	{
6116 		GrMaskFocalX = is->getDouble("NEWX");
6117 		GrMaskFocalY = is->getDouble("NEWY");
6118 	}
6119 }
6120 
restoreGradientMaskScale(SimpleState * is,bool isUndo)6121 void PageItem::restoreGradientMaskScale(SimpleState *is, bool isUndo)
6122 {
6123 	if (isUndo)
6124 		GrMaskScale= is->getDouble("OLD");
6125 	else
6126 		GrMaskScale = is->getDouble("NEW");
6127 }
6128 
restoreGradientMaskSkew(SimpleState * is,bool isUndo)6129 void PageItem::restoreGradientMaskSkew(SimpleState *is, bool isUndo)
6130 {
6131 	if (isUndo)
6132 		GrMaskSkew = is->getDouble("OLD");
6133 	else
6134 		GrMaskSkew = is->getDouble("NEW");
6135 }
6136 
restoreGradientControl1(SimpleState * state,bool isUndo)6137 void PageItem::restoreGradientControl1(SimpleState *state, bool isUndo)
6138 {
6139 	ScItemState<QPair<FPoint,FPoint> > *is = dynamic_cast<ScItemState<QPair<FPoint,FPoint> > *>(state);
6140 	if (!is)
6141 		qFatal("PageItem::restoreGradientControl1: dynamic cast failed");
6142 	if (isUndo)
6143 		GrControl1 = is->getItem().first;
6144 	else
6145 		GrControl1 = is->getItem().second;
6146 }
6147 
restoreGradientControl2(SimpleState * state,bool isUndo)6148 void PageItem::restoreGradientControl2(SimpleState *state, bool isUndo)
6149 {
6150 	ScItemState<QPair<FPoint,FPoint> > *is = dynamic_cast<ScItemState<QPair<FPoint,FPoint> > *>(state);
6151 	if (!is)
6152 		qFatal("PageItem::restoreGradientControl2: dynamic cast failed");
6153 	if (isUndo)
6154 		GrControl2 = is->getItem().first;
6155 	else
6156 		GrControl2 = is->getItem().second;
6157 }
6158 
restoreGradientControl3(SimpleState * state,bool isUndo)6159 void PageItem::restoreGradientControl3(SimpleState *state, bool isUndo)
6160 {
6161 	ScItemState<QPair<FPoint,FPoint> > *is = dynamic_cast<ScItemState<QPair<FPoint,FPoint> > *>(state);
6162 	if (!is)
6163 		qFatal("PageItem::restoreGradientControl3: dynamic cast failed");
6164 	if (isUndo)
6165 		GrControl3 = is->getItem().first;
6166 	else
6167 		GrControl3 = is->getItem().second;
6168 }
6169 
restoreGradientControl4(SimpleState * state,bool isUndo)6170 void PageItem::restoreGradientControl4(SimpleState *state, bool isUndo)
6171 {
6172 	ScItemState<QPair<FPoint,FPoint> > *is = dynamic_cast<ScItemState<QPair<FPoint,FPoint> > *>(state);
6173 	if (!is)
6174 		qFatal("PageItem::restoreGradientControl4: dynamic cast failed");
6175 	if (isUndo)
6176 		GrControl4 = is->getItem().first;
6177 	else
6178 		GrControl4 = is->getItem().second;
6179 }
6180 
restoreGradientControl5(SimpleState * state,bool isUndo)6181 void PageItem::restoreGradientControl5(SimpleState *state, bool isUndo)
6182 {
6183 	ScItemState<QPair<FPoint,FPoint> > *is = dynamic_cast<ScItemState<QPair<FPoint,FPoint> > *>(state);
6184 	if (!is)
6185 		qFatal("PageItem::restoreGradientControl5: dynamic cast failed");
6186 	if (isUndo)
6187 		GrControl5 = is->getItem().first;
6188 	else
6189 		GrControl5 = is->getItem().second;
6190 }
6191 
restoreGradientStrokeScale(SimpleState * is,bool isUndo)6192 void PageItem::restoreGradientStrokeScale(SimpleState *is, bool isUndo)
6193 {
6194 	if (isUndo)
6195 		GrStrokeScale = is->getDouble("OLD");
6196 	else
6197 		GrStrokeScale = is->getDouble("NEW");
6198 }
6199 
restoreGradientStrokeSkew(SimpleState * is,bool isUndo)6200 void PageItem::restoreGradientStrokeSkew(SimpleState *is, bool isUndo)
6201 {
6202 	if (isUndo)
6203 		GrStrokeSkew = is->getDouble("OLD");
6204 	else
6205 		GrStrokeSkew = is->getDouble("NEW");
6206 }
6207 
restoreGradientStrokeFocal(SimpleState * is,bool isUndo)6208 void PageItem::restoreGradientStrokeFocal(SimpleState *is, bool isUndo)
6209 {
6210 	if (isUndo)
6211 	{
6212 		GrStrokeFocalX = is->getDouble("OLDX");
6213 		GrStrokeFocalY = is->getDouble("OLDY");
6214 	}
6215 	else
6216 	{
6217 		GrStrokeFocalX = is->getDouble("NEWX");
6218 		GrStrokeFocalY = is->getDouble("NEWY");
6219 	}
6220 }
6221 
restoreGradientStrokeStart(SimpleState * is,bool isUndo)6222 void PageItem::restoreGradientStrokeStart(SimpleState *is, bool isUndo)
6223 {
6224 	if (isUndo)
6225 	{
6226 		GrStrokeStartX = is->getDouble("OLDX");
6227 		GrStrokeStartY = is->getDouble("OLDY");
6228 	}
6229 	else
6230 	{
6231 		GrStrokeStartX = is->getDouble("NEWX");
6232 		GrStrokeStartY = is->getDouble("NEWY");
6233 	}
6234 }
6235 
restoreGradientStrokeEnd(SimpleState * is,bool isUndo)6236 void PageItem::restoreGradientStrokeEnd(SimpleState *is, bool isUndo)
6237 {
6238 	if (isUndo)
6239 	{
6240 		GrStrokeEndX = is->getDouble("OLDX");
6241 		GrStrokeEndY = is->getDouble("OLDY");
6242 	}
6243 	else
6244 	{
6245 		GrStrokeEndX = is->getDouble("NEWX");
6246 		GrStrokeEndY = is->getDouble("NEWY");
6247 	}
6248 }
6249 
restoreGradientType(SimpleState * is,bool isUndo)6250 void PageItem::restoreGradientType(SimpleState *is, bool isUndo)
6251 {
6252 	if (isUndo)
6253 		GrType = is->getInt("OLD");
6254 	else
6255 		GrType = is->getInt("NEW");
6256 }
6257 
restoreGradientTypeStroke(SimpleState * is,bool isUndo)6258 void PageItem::restoreGradientTypeStroke(SimpleState *is, bool isUndo)
6259 {
6260 	if (isUndo)
6261 		GrTypeStroke = is->getInt("OLD");
6262 	else
6263 		GrTypeStroke = is->getInt("NEW");
6264 }
6265 
restoreEndArrowScale(SimpleState * is,bool isUndo)6266 void PageItem::restoreEndArrowScale(SimpleState *is, bool isUndo)
6267 {
6268 	if (isUndo)
6269 		m_endArrowScale = is->getInt("OLD_SCALE");
6270 	else
6271 		m_endArrowScale = is->getInt("NEW_SCALE");
6272 }
6273 
restoreStartArrowScale(SimpleState * is,bool isUndo)6274 void PageItem::restoreStartArrowScale(SimpleState *is, bool isUndo)
6275 {
6276 	if (isUndo)
6277 		m_startArrowScale = is->getInt("OLD_SCALE");
6278 	else
6279 		m_startArrowScale = is->getInt("NEW_SCALE");
6280 }
6281 
restoreImageRotation(SimpleState * is,bool isUndo)6282 void PageItem::restoreImageRotation(SimpleState *is, bool isUndo)
6283 {
6284 	if (isUndo)
6285 		m_imageRotation = is->getInt("OLD_ROT");
6286 	else
6287 		m_imageRotation = is->getInt("NEW_ROT");
6288 }
6289 
restorePasteInline(SimpleState * is,bool isUndo)6290 void PageItem::restorePasteInline(SimpleState *is, bool isUndo)
6291 {
6292 	int start = is->getInt("START");
6293 	if (isUndo)
6294 	{
6295 		itemText.select(start,1);
6296 		asTextFrame()->deleteSelectedTextFromFrame();
6297 	}
6298 	else
6299 		itemText.insertObject(is->getInt("INDEX"));
6300 }
6301 
restorePastePlainText(SimpleState * ss,bool isUndo)6302 void PageItem::restorePastePlainText(SimpleState *ss, bool isUndo)
6303 {
6304 	int start = ss->getInt("START");
6305 	QString text(ss->get("TEXT"));
6306 
6307 	itemText.deselectAll();
6308 	if (isUndo)
6309 	{
6310 		itemText.select(start, text.length());
6311 		asTextFrame()->deleteSelectedTextFromFrame();
6312 	}
6313 	else
6314 	{
6315 		itemText.insertChars(start, text, true);
6316 		itemText.setCursorPosition(start + text.length());
6317 	}
6318 }
6319 
restorePasteText(SimpleState * ss,bool isUndo)6320 void PageItem::restorePasteText(SimpleState *ss, bool isUndo)
6321 {
6322 	ScItemState<StoryText> *is = dynamic_cast<ScItemState<StoryText>*>(ss);
6323 	if (!is)
6324 		qFatal("PageItem::restorePasteText: dynamic cast failed");
6325 
6326 	int start = is->getInt("START");
6327 	itemText.deselectAll();
6328 	if (isUndo)
6329 	{
6330 		itemText.select(start, is->getItem().length());
6331 		asTextFrame()->deleteSelectedTextFromFrame();
6332 	}
6333 	else
6334 	{
6335 		itemText.insert(start, is->getItem());
6336 		itemText.setCursorPosition(start + is->getItem().length());
6337 	}
6338 }
6339 
restoreColumnsGap(SimpleState * ss,bool isUndo)6340 void PageItem::restoreColumnsGap(SimpleState *ss, bool isUndo)
6341 {
6342 	if (isUndo)
6343 		m_columnGap = ss->getDouble("OLD_COLUMNS");
6344 	else
6345 		m_columnGap = ss->getDouble("NEW_COLUMNS");
6346 	update();
6347 }
6348 
restoreLeftTextFrameDist(SimpleState * ss,bool isUndo)6349 void PageItem::restoreLeftTextFrameDist(SimpleState *ss, bool isUndo)
6350 {
6351 	if (isUndo)
6352 		m_textDistanceMargins.setLeft(ss->getDouble("OLD_DIST"));
6353 	else
6354 		m_textDistanceMargins.setLeft(ss->getDouble("NEW_DIST"));
6355 	update();
6356 }
6357 
restoreRightTextFrameDist(SimpleState * ss,bool isUndo)6358 void PageItem::restoreRightTextFrameDist(SimpleState *ss, bool isUndo)
6359 {
6360 	if (isUndo)
6361 		m_textDistanceMargins.setRight(ss->getDouble("OLD_DIST"));
6362 	else
6363 		m_textDistanceMargins.setRight(ss->getDouble("NEW_DIST"));
6364 	update();
6365 }
6366 
restoreTopTextFrameDist(SimpleState * ss,bool isUndo)6367 void PageItem::restoreTopTextFrameDist(SimpleState *ss, bool isUndo)
6368 {
6369 	if (isUndo)
6370 		m_textDistanceMargins.setTop(ss->getDouble("OLD_DIST"));
6371 	else
6372 		m_textDistanceMargins.setTop(ss->getDouble("NEW_DIST"));
6373 	update();
6374 }
6375 
restoreBottomTextFrameDist(SimpleState * ss,bool isUndo)6376 void PageItem::restoreBottomTextFrameDist(SimpleState *ss, bool isUndo)
6377 {
6378 	if (isUndo)
6379 		m_textDistanceMargins.setBottom(ss->getDouble("OLD_DIST"));
6380 	else
6381 		m_textDistanceMargins.setBottom(ss->getDouble("NEW_DIST"));
6382 	update();
6383 }
6384 
restoreColumns(SimpleState * ss,bool isUndo)6385 void PageItem::restoreColumns(SimpleState *ss, bool isUndo)
6386 {
6387 	if (isUndo)
6388 		m_columns = ss->getInt("OLD_COLUMNS");
6389 	else
6390 		m_columns = ss->getInt("NEW_COLUMNS");
6391 	update();
6392 }
6393 
restoreFirstLineOffset(SimpleState * ss,bool isUndo)6394 void PageItem::restoreFirstLineOffset(SimpleState *ss, bool isUndo)
6395 {
6396 	ScItemState<QPair<FirstLineOffsetPolicy, FirstLineOffsetPolicy > > *is = dynamic_cast<ScItemState<QPair<FirstLineOffsetPolicy, FirstLineOffsetPolicy> >*>(ss);
6397 	if (!is)
6398 		qFatal("PageItem::restoreFirstLineOffset: dynamic cast failed");
6399 	if (isUndo)
6400 		m_firstLineOffset = is->getItem().first;
6401 	else
6402 		m_firstLineOffset = is->getItem().second;
6403 	update();
6404 }
6405 
restoreDefaultParagraphStyle(SimpleState * ss,bool isUndo)6406 void PageItem::restoreDefaultParagraphStyle(SimpleState *ss, bool isUndo)
6407 {
6408 	ScItemState<QPair<ParagraphStyle, ParagraphStyle > > *is = dynamic_cast<ScItemState<QPair<ParagraphStyle, ParagraphStyle> >*>(ss);
6409 	if (!is)
6410 		qFatal("PageItem::restoreDefaultParagraphStyle: dynamic cast failed");
6411 	if (isUndo)
6412 		itemText.setDefaultStyle(is->getItem().second);
6413 	else
6414 		itemText.setDefaultStyle(is->getItem().first);
6415 }
6416 
restoreParagraphStyle(SimpleState * ss,bool isUndo)6417 void PageItem::restoreParagraphStyle(SimpleState *ss, bool isUndo)
6418 {
6419 	ScItemState<QPair<ParagraphStyle, ParagraphStyle > > *is = dynamic_cast<ScItemState<QPair<ParagraphStyle, ParagraphStyle> >*>(ss);
6420 	if (!is)
6421 		qFatal("PageItem::restoreParagraphStyle: dynamic cast failed");
6422 	int pos = is->getInt("POS");
6423 	if (isUndo)
6424 	{
6425 		itemText.eraseStyle(pos, is->getItem().first);
6426 		itemText.applyStyle(pos, is->getItem().second);
6427 	}
6428 	else
6429 		itemText.applyStyle(pos, is->getItem().first);
6430 }
6431 
restoreCharStyle(SimpleState * ss,bool isUndo)6432 void PageItem::restoreCharStyle(SimpleState *ss, bool isUndo)
6433 {
6434 	ScItemState<QPair<CharStyle, CharStyle > > *is = dynamic_cast<ScItemState<QPair<CharStyle, CharStyle> >*>(ss);
6435 	if (!is)
6436 		qFatal("PageItem::restoreCharStyle: dynamic cast failed");
6437 	int length = is->getInt("LENGTH");
6438 	int start = is->getInt("START");
6439 	if (isUndo)
6440 	{
6441 		itemText.eraseCharStyle(start,length, is->getItem().first);
6442 		itemText.applyCharStyle(start,length, is->getItem().second);
6443 	}
6444 	else
6445 		itemText.applyCharStyle(start,length, is->getItem().first);
6446 }
6447 
restoreSetCharStyle(SimpleState * ss,bool isUndo)6448 void PageItem::restoreSetCharStyle(SimpleState *ss, bool isUndo)
6449 {
6450 	ScItemState<QPair<CharStyle, CharStyle > > *is = dynamic_cast<ScItemState<QPair<CharStyle, CharStyle> >*>(ss);
6451 	if (!is)
6452 		qFatal("PageItem::restoreSetCharStyle: dynamic cast failed");
6453 	int length = is->getInt("LENGTH");
6454 	int start = is->getInt("START");
6455 	if (isUndo)
6456 		itemText.setCharStyle(start, length, is->getItem().second);
6457 	else
6458 		itemText.setCharStyle(start, length, is->getItem().first);
6459 }
6460 
restoreSetParagraphStyle(SimpleState * ss,bool isUndo)6461 void PageItem::restoreSetParagraphStyle(SimpleState *ss, bool isUndo)
6462 {
6463 	ScItemState<QPair<ParagraphStyle, ParagraphStyle > > *is = dynamic_cast<ScItemState<QPair<ParagraphStyle, ParagraphStyle> >*>(ss);
6464 	if (!is)
6465 		qFatal("PageItem::restoreSetParagraphStyle: dynamic cast failed");
6466 	int pos = is->getInt("POS");
6467 	if (isUndo)
6468 		itemText.setStyle(pos, is->getItem().second);
6469 	else
6470 		itemText.setStyle(pos, is->getItem().first);
6471 }
6472 
restoreDeleteFrameText(SimpleState * ss,bool isUndo)6473 void PageItem::restoreDeleteFrameText(SimpleState *ss, bool isUndo)
6474 {
6475 	ScItemState<CharStyle> *is = dynamic_cast<ScItemState<CharStyle> *>(ss);
6476 	if (!is)
6477 		qFatal("PageItem::restoreDeleteFrameText: dynamic cast failed");
6478 
6479 	QString text(is->get("TEXT_STR"));
6480 	int start = is->getInt("START");
6481 	itemText.deselectAll();
6482 	if (isUndo)
6483 	{
6484 		itemText.insertChars(start, text);
6485 		itemText.applyCharStyle(start, text.length(), is->getItem());
6486 		itemText.setCursorPosition(start + text.length());
6487 		invalid = true;
6488 		invalidateLayout();
6489 	}
6490 	else
6491 	{
6492 		itemText.select(start, text.length());
6493 		asTextFrame()->deleteSelectedTextFromFrame();
6494 	}
6495 	update();
6496 }
6497 
restoreDeleteFrameParagraph(SimpleState * ss,bool isUndo)6498 void PageItem::restoreDeleteFrameParagraph(SimpleState *ss, bool isUndo)
6499 {
6500 	ScItemState<ParagraphStyle> *is = dynamic_cast<ScItemState<ParagraphStyle> *>(ss);
6501 	if (!is)
6502 		qFatal("PageItem::restoreDeleteFrameParagraph: dynamic cast failed");
6503 
6504 	int start = is->getInt("START");
6505 	itemText.deselectAll();
6506 	if (isUndo)
6507 	{
6508 		itemText.insertChars(start, SpecialChars::PARSEP);
6509 		itemText.applyStyle(start, is->getItem());
6510 		itemText.setCursorPosition(start + 1);
6511 		invalid = true;
6512 		invalidateLayout();
6513 	}
6514 	else
6515 	{
6516 		itemText.select(start, 1);
6517 		asTextFrame()->deleteSelectedTextFromFrame();
6518 	}
6519 	update();
6520 }
6521 
restoreInsertFrameText(SimpleState * ss,bool isUndo)6522 void PageItem::restoreInsertFrameText(SimpleState *ss, bool isUndo)
6523 {
6524 	QString text(ss->get("TEXT_STR"));
6525 	int start = ss->getInt("START");
6526 
6527 	itemText.deselectAll();
6528 	if (isUndo)
6529 	{
6530 		itemText.select(start, text.length());
6531 		asTextFrame()->deleteSelectedTextFromFrame();
6532 	}
6533 	else
6534 	{
6535 		itemText.insertChars(start, text);
6536 		itemText.setCursorPosition(start + text.length());
6537 	}
6538 }
6539 
restoreInsertFrameParagraph(SimpleState * ss,bool isUndo)6540 void PageItem::restoreInsertFrameParagraph(SimpleState *ss, bool isUndo)
6541 {
6542 	ScItemState<ParagraphStyle> *is = dynamic_cast<ScItemState<ParagraphStyle> *>(ss);
6543 	if (!is)
6544 		qFatal("PageItem::restoreInsertFrameParagraph: dynamic cast failed");
6545 
6546 	int start = is->getInt("START");
6547 	itemText.deselectAll();
6548 	if (isUndo)
6549 	{
6550 		itemText.select(start, 1);
6551 		asTextFrame()->deleteSelectedTextFromFrame();
6552 		itemText.applyStyle(start, is->getItem());
6553 	}
6554 	else
6555 	{
6556 		itemText.insertChars(start, SpecialChars::PARSEP);
6557 		itemText.setCursorPosition(start + 1);
6558 		invalid = true;
6559 		invalidateLayout();
6560 	}
6561 	update();
6562 }
6563 
restoreCornerRadius(SimpleState * state,bool isUndo)6564 void PageItem::restoreCornerRadius(SimpleState *state, bool isUndo)
6565 {
6566 	if (isUndo)
6567 		m_roundedCornerRadius = state->getDouble("OLD_RADIUS");
6568 	else
6569 		m_roundedCornerRadius = state->getDouble("NEW_RADIUS");
6570 	Selection tmpSelection = *(doc()->m_Selection);
6571 	doc()->m_Selection->clear();
6572 	doc()->m_Selection->addItem(this);
6573 	doc()->setFrameRounded();
6574 	*(doc()->m_Selection) = tmpSelection;
6575 }
6576 
restoreMove(SimpleState * state,bool isUndo)6577 void PageItem::restoreMove(SimpleState *state, bool isUndo)
6578 {
6579 	double ox = state->getDouble("OLD_XPOS");
6580 	double oy = state->getDouble("OLD_YPOS");
6581 	double  x = state->getDouble("NEW_XPOS");
6582 	double  y = state->getDouble("NEW_YPOS");
6583 	double mx = ox - x;
6584 	double my = oy - y;
6585 	if (!isUndo)
6586 	{
6587 		mx = -mx;
6588 		my = -my;
6589 	}
6590 	m_Doc->moveItem(mx, my, this);
6591 	oldXpos = m_xPos;
6592 	oldYpos = m_yPos;
6593 	oldOwnPage = OwnPage;
6594 }
6595 
restoreResize(SimpleState * state,bool isUndo)6596 void PageItem::restoreResize(SimpleState *state, bool isUndo)
6597 {
6598 	double  ow = state->getDouble("OLD_WIDTH");
6599 	double  oh = state->getDouble("OLD_HEIGHT");
6600 	double   w = state->getDouble("NEW_WIDTH");
6601 	double   h = state->getDouble("NEW_HEIGHT");
6602 	double  ox = state->getDouble("OLD_RXPOS");
6603 	double  oy = state->getDouble("OLD_RYPOS");
6604 	double   x = state->getDouble("NEW_RXPOS");
6605 	double   y = state->getDouble("NEW_RYPOS");
6606 	double ort = state->getDouble("OLD_RROT");
6607 	double  rt = state->getDouble("NEW_RROT");
6608 	double  mx = ox - x;
6609 	double  my = oy - y;
6610 	int  stateCode = state->transactionCode;
6611 	bool redraw = ((stateCode != 1) && (stateCode != 3));
6612 	if (isUndo)
6613 	{
6614 		m_Doc->sizeItem(ow, oh, this, false, true, redraw);
6615 		m_Doc->moveItem(mx, my, this);
6616 		m_Doc->rotateItem(ort, this);
6617 	}
6618 	else
6619 	{
6620 		mx = -mx;
6621 		my = -my;
6622 		m_Doc->sizeItem(w, h, this, false, true, redraw);
6623 		m_Doc->moveItem(mx, my, this);
6624 		m_Doc->rotateItem(rt, this);
6625 	}
6626 	oldWidth = m_width;
6627 	oldHeight = m_height;
6628 	oldXpos = m_xPos;
6629 	oldYpos = m_yPos;
6630 	oldOwnPage = OwnPage;
6631 	oldRot = m_rotation;
6632 }
6633 
restoreRotate(SimpleState * state,bool isUndo)6634 void PageItem::restoreRotate(SimpleState *state, bool isUndo)
6635 {
6636 	double ort = state->getDouble("OLD_ROT");
6637 	double  rt = state->getDouble("NEW_ROT");
6638 	double  ox = state->getDouble("OLD_RXPOS");
6639 	double  oy = state->getDouble("OLD_RYPOS");
6640 	double   x = state->getDouble("NEW_RXPOS");
6641 	double   y = state->getDouble("NEW_RYPOS");
6642 	double  ow = state->getDouble("OLD_RWIDTH");
6643 	double  oh = state->getDouble("OLD_RHEIGHT");
6644 	double   w = state->getDouble("NEW_RWIDTH");
6645 	double   h = state->getDouble("NEW_RHEIGHT");
6646 	int  stateCode = state->transactionCode;
6647 	bool redraw = ((stateCode != 1) && (stateCode != 3));
6648 	if (isUndo)
6649 	{
6650 		m_Doc->rotateItem(ort, this);
6651 		m_Doc->moveItem(ox - m_xPos, oy - m_yPos, this);
6652 		m_Doc->sizeItem(ow, oh, this, false, true, redraw);
6653 	}
6654 	else
6655 	{
6656 		m_Doc->rotateItem(rt, this);
6657 		m_Doc->moveItem(x - m_xPos, y - m_yPos, this);
6658 		m_Doc->sizeItem(w, h, this, false, true, redraw);
6659 	}
6660 	oldRot = m_rotation;
6661 	oldXpos = m_xPos;
6662 	oldYpos = m_yPos;
6663 	oldOwnPage = OwnPage;
6664 	oldWidth = m_width;
6665 	oldHeight = m_height;
6666 }
6667 
restoreShowImage(SimpleState * state,bool isUndo)6668 void PageItem::restoreShowImage(SimpleState *state, bool isUndo)
6669 {
6670 	bool old = state->getBool("OLD");
6671 	if (isUndo)
6672 		m_imageVisible = old;
6673 	else
6674 		m_imageVisible = !old;
6675 	update();
6676 }
6677 
restoreFill(SimpleState * state,bool isUndo)6678 void PageItem::restoreFill(SimpleState *state, bool isUndo)
6679 {
6680 	QString fill(state->get("OLD_FILL"));
6681 	if (!isUndo)
6682 		fill = state->get("NEW_FILL");
6683 	Selection tempSelection(0, false);
6684 	tempSelection.addItem(this);
6685 	m_Doc->itemSelection_SetItemBrush(fill, &tempSelection);
6686 }
6687 
restoreResTyp(SimpleState * state,bool isUndo)6688 void PageItem::restoreResTyp(SimpleState *state, bool isUndo)
6689 {
6690 	if (isUndo)
6691 		setResolution(state->getInt("OLD_RES"));
6692 	else
6693 		setResolution(state->getInt("NEW_RES"));
6694 	doc()->updatePic();
6695 }
6696 
restoreShade(SimpleState * state,bool isUndo)6697 void PageItem::restoreShade(SimpleState *state, bool isUndo)
6698 {
6699 	int shade = state->getInt("OLD_SHADE");
6700 	if (!isUndo)
6701 		shade = state->getInt("NEW_SHADE");
6702 	Selection tempSelection(0, false);
6703 	tempSelection.addItem(this);
6704 	m_Doc->itemSelection_SetItemBrushShade(shade, &tempSelection);
6705 }
6706 
restoreLineColor(SimpleState * state,bool isUndo)6707 void PageItem::restoreLineColor(SimpleState *state, bool isUndo)
6708 {
6709 	QString fill(state->get("OLD_COLOR"));
6710 	if (!isUndo)
6711 		fill = state->get("NEW_COLOR");
6712 	Selection tempSelection(0, false);
6713 	tempSelection.addItem(this);
6714 	m_Doc->itemSelection_SetItemPen(fill, &tempSelection);
6715 }
6716 
restoreLineShade(SimpleState * state,bool isUndo)6717 void PageItem::restoreLineShade(SimpleState *state, bool isUndo)
6718 {
6719 	int shade = state->getInt("OLD_SHADE");
6720 	if (!isUndo)
6721 		shade = state->getInt("NEW_SHADE");
6722 	Selection tempSelection(0, false);
6723 	tempSelection.addItem(this);
6724 	m_Doc->itemSelection_SetItemPenShade(shade, &tempSelection);
6725 }
6726 
restoreFillTP(SimpleState * state,bool isUndo)6727 void PageItem::restoreFillTP(SimpleState *state, bool isUndo)
6728 {
6729 	double tp = state->getDouble("OLD_TP");
6730 	if (!isUndo)
6731 		tp = state->getDouble("NEW_TP");
6732 	Selection tempSelection(0, false);
6733 	tempSelection.addItem(this);
6734 	m_Doc->itemSelection_SetItemFillTransparency(tp, &tempSelection);
6735 }
6736 
restoreLineTP(SimpleState * state,bool isUndo)6737 void PageItem::restoreLineTP(SimpleState *state, bool isUndo)
6738 {
6739 	double tp = state->getDouble("OLD_TP");
6740 	if (!isUndo)
6741 		tp = state->getDouble("NEW_TP");
6742 	Selection tempSelection(0, false);
6743 	tempSelection.addItem(this);
6744 	m_Doc->itemSelection_SetItemLineTransparency(tp, &tempSelection);
6745 }
6746 
6747 
restoreLineStyle(SimpleState * state,bool isUndo)6748 void PageItem::restoreLineStyle(SimpleState *state, bool isUndo)
6749 {
6750 	Qt::PenStyle ps = static_cast<Qt::PenStyle>(state->getInt("OLD_STYLE"));
6751 	if (!isUndo)
6752 		ps = static_cast<Qt::PenStyle>(state->getInt("NEW_STYLE"));
6753 	Selection tempSelection(0, false);
6754 	tempSelection.addItem(this);
6755 	m_Doc->itemSelection_SetLineArt(ps, &tempSelection);
6756 }
6757 
restoreLineEnd(SimpleState * state,bool isUndo)6758 void PageItem::restoreLineEnd(SimpleState *state, bool isUndo)
6759 {
6760 	Qt::PenCapStyle pcs = static_cast<Qt::PenCapStyle>(state->getInt("OLD_STYLE"));
6761 	if (!isUndo)
6762 		pcs = static_cast<Qt::PenCapStyle>(state->getInt("NEW_STYLE"));
6763 	Selection tempSelection(0, false);
6764 	tempSelection.addItem(this);
6765 	m_Doc->itemSelection_SetLineEnd(pcs, &tempSelection);
6766 }
6767 
restoreLineJoin(SimpleState * state,bool isUndo)6768 void PageItem::restoreLineJoin(SimpleState *state, bool isUndo)
6769 {
6770 	Qt::PenJoinStyle pjs = static_cast<Qt::PenJoinStyle>(state->getInt("OLD_STYLE"));
6771 	if (!isUndo)
6772 		pjs = static_cast<Qt::PenJoinStyle>(state->getInt("NEW_STYLE"));
6773 	Selection tempSelection(0, false);
6774 	tempSelection.addItem(this);
6775 	m_Doc->itemSelection_SetLineJoin(pjs, &tempSelection);
6776 }
6777 
restoreLineWidth(SimpleState * state,bool isUndo)6778 void PageItem::restoreLineWidth(SimpleState *state, bool isUndo)
6779 {
6780 	double w = state->getDouble("OLD_LINEWIDTH");
6781 	if (!isUndo)
6782 		w = state->getDouble("NEW_LINEWIDTH");
6783 	Selection tempSelection(0, false);
6784 	tempSelection.addItem(this);
6785 	m_Doc->itemSelection_SetLineWidth(w, &tempSelection);
6786 }
6787 
restoreCustomLineStyle(SimpleState * state,bool isUndo)6788 void PageItem::restoreCustomLineStyle(SimpleState *state, bool isUndo)
6789 {
6790 	QString style(state->get("OLD_STYLE"));
6791 	if (!isUndo)
6792 		style = state->get("NEW_STYLE");
6793 	setCustomLineStyle(style);
6794 }
6795 
restoreName(SimpleState * state,bool isUndo)6796 void PageItem::restoreName(SimpleState *state, bool isUndo)
6797 {
6798 	QString name(state->get("OLD_NAME"));
6799 	if (!isUndo)
6800 		name = state->get("NEW_NAME");
6801 	setItemName(name);
6802 }
6803 
restoreArrow(SimpleState * state,bool isUndo,bool isStart)6804 void PageItem::restoreArrow(SimpleState *state, bool isUndo, bool isStart)
6805 {
6806 	int i = state->getInt("OLD_INDEX");
6807 	if (!isUndo)
6808 		i = state->getInt("NEW_INDEX");
6809 	if (isStart)
6810 		setStartArrowIndex(i);
6811 	else
6812 		setEndArrowIndex(i);
6813 }
6814 
6815 
restorePStyle(SimpleState * state,bool isUndo)6816 void PageItem::restorePStyle(SimpleState *state, bool isUndo)
6817 {
6818 	Q_UNUSED(state);
6819 	Q_UNUSED(isUndo);
6820 	//int styleid = state->getInt("OLD_STYLE");
6821 	//if (!isUndo)
6822 	//	styleid = state->getInt("NEW_STYLE");
6823 	//will be done later with other text-undo:
6824 	//	m_Doc->chAbStyle(this, styleid);
6825 }
6826 
6827 
6828 // FIXME: This must go into class ScribusDoc!
6829 // For now we'll just make it independent of 'this' -- AV
restoreType(SimpleState * state,bool isUndo)6830 void PageItem::restoreType(SimpleState *state, bool isUndo)
6831 {
6832 	PageItem * item = reinterpret_cast<PageItem *>(state->getVoidPtr("PAGEITEM"));
6833 	int type = state->getInt("OLD_TYPE");
6834 	if (!isUndo)
6835 		type = state->getInt("NEW_TYPE");
6836 	ScribusView* view = m_Doc->view();
6837 	view->deselectItems(false);
6838 	view->selectItem(item, false);
6839 	switch (type)
6840 	{
6841 		case ImageFrame: view->ToPicFrame(); break;
6842 		case TextFrame: view->ToTextFrame(); break;
6843 		case Polygon: view->ToPolyFrame(); break;
6844 		case PolyLine: view->ToBezierFrame(); break;
6845 	}
6846 	view->requestMode(modeNormal);
6847 }
6848 
restoreTextFlowing(SimpleState * state,bool isUndo)6849 void PageItem::restoreTextFlowing(SimpleState *state, bool isUndo)
6850 {
6851 	TextFlowMode oldMode = (TextFlowMode) state->getInt("TEXTFLOW_OLDMODE");
6852 	TextFlowMode newMode = (TextFlowMode) state->getInt("TEXTFLOW_NEWMODE");
6853 	if (isUndo)
6854 		m_textFlowMode = oldMode;
6855 	else
6856 		m_textFlowMode = newMode;
6857 
6858 	QList<PageItem*> pList;
6859 	int id = m_Doc->Items->indexOf(this) - 1;
6860 	for (int i = id; i >= 0 ; --i)
6861 		pList << m_Doc->Items->at(i);
6862 
6863 	QRectF baseRect(getBoundingRect());
6864 	for (int i = 0; i < pList.count(); ++i)
6865 	{
6866 		QRectF uRect(pList.at(i)->getBoundingRect());
6867 		if (baseRect.intersects(uRect))
6868 			pList.at(i)->update();
6869 	}
6870 }
6871 
restoreImageScaleMode(SimpleState * state,bool isUndo)6872 void PageItem::restoreImageScaleMode(SimpleState *state, bool isUndo)
6873 {
6874 	bool type=ScaleType;
6875 	if (state->contains("SCALE_TYPE"))
6876 	{
6877 		if (isUndo)
6878 			type = !state->getBool("SCALE_TYPE");
6879 		else
6880 			type = state->getBool("SCALE_TYPE");
6881 		//if restoring free scaling
6882 		//old offset and scale ratio must be restored
6883 		if (type)
6884 		{
6885 			double oscx = state->getDouble("OLD_IMAGEXSCALE");
6886 			double oscy = state->getDouble("OLD_IMAGEYSCALE");
6887 			double ox = state->getDouble("OLD_IMAGEXOFFSET");
6888 			double oy = state->getDouble("OLD_IMAGEYOFFSET");
6889 			Selection tempSelection(this, false);
6890 			tempSelection.addItem(this, true);
6891 			m_Doc->itemSelection_SetImageScale(oscx, oscy, &tempSelection);
6892 			m_Doc->itemSelection_SetImageOffset(ox, oy, &tempSelection);
6893 		}
6894 		else
6895 		{
6896 			state->set("OLD_IMAGEXOFFSET", m_imageXOffset);
6897 			state->set("OLD_IMAGEYOFFSET", m_imageYOffset);
6898 			state->set("OLD_IMAGEXSCALE", m_imageXScale);
6899 			state->set("OLD_IMAGEYSCALE", m_imageYScale);
6900 		}
6901 	}
6902 
6903 	bool ratio=AspectRatio;
6904 	if (state->contains("ASPECT_RATIO"))
6905 	{
6906 		if (isUndo)
6907 			ratio = !state->getBool("ASPECT_RATIO");
6908 		else
6909 			ratio = state->getBool("ASPECT_RATIO");
6910 	}
6911 
6912 	setImageScalingMode(type, ratio);
6913 }
6914 
restoreImageScaleChange(SimpleState * state,bool isUndo)6915 void PageItem::restoreImageScaleChange(SimpleState *state, bool isUndo)
6916 {
6917 	double oscx = state->getDouble("OLD_IMAGEXSCALE");
6918 	double oscy = state->getDouble("OLD_IMAGEYSCALE");
6919 	double  scx = state->getDouble("NEW_IMAGEXSCALE");
6920 	double  scy = state->getDouble("NEW_IMAGEYSCALE");
6921 	Selection tempSelection(this, false);
6922 	tempSelection.addItem(this, true);
6923 	if (!isUndo)
6924 		m_Doc->itemSelection_SetImageScale(scx, scy, &tempSelection);
6925 	else
6926 		m_Doc->itemSelection_SetImageScale(oscx, oscy, &tempSelection);
6927 }
6928 
restoreImageOffsetChange(SimpleState * state,bool isUndo)6929 void PageItem::restoreImageOffsetChange(SimpleState *state, bool isUndo)
6930 {
6931 	double ox = state->getDouble("OLD_IMAGEXOFFSET");
6932 	double oy = state->getDouble("OLD_IMAGEYOFFSET");
6933 	double  x = state->getDouble("NEW_IMAGEXOFFSET");
6934 	double  y = state->getDouble("NEW_IMAGEYOFFSET");
6935 	Selection tempSelection(this, false);
6936 	tempSelection.addItem(this, true);
6937 	if (!isUndo)
6938 		m_Doc->itemSelection_SetImageOffset(x, y, &tempSelection);
6939 	else
6940 		m_Doc->itemSelection_SetImageOffset(ox, oy, &tempSelection);
6941 }
6942 
restoreClearImage(UndoState * state,bool isUndo)6943 void PageItem::restoreClearImage(UndoState *state, bool isUndo)
6944 {
6945 	if (!isImageFrame())
6946 		return;
6947 	if (isUndo)
6948 	{
6949 		ScItemState<ScImageEffectList>* is = dynamic_cast<ScItemState<ScImageEffectList>*>(state);
6950 		if (!is)
6951 			qFatal("PageItem::restoreClearImage: dynamic cast failed");
6952 		Pfile = is->get("CI_PFILE");
6953 		loadImage(Pfile, false);
6954 		effectsInUse = is->getItem();
6955 		setImageFlippedH(is->getBool("CI_FLIPPH"));
6956 		setImageFlippedV(is->getBool("CI_FLIPPV"));
6957 		setImageScalingMode(is->getBool("CI_SCALING"),is->getBool("CI_ASPECT"));
6958 		setImageXOffset(is->getDouble("CI_XOFF"));
6959 		setImageXScale(is->getDouble("CI_XSCALE"));
6960 		setImageYOffset(is->getDouble("CI_YOFF"));
6961 		setImageYScale(is->getDouble("CI_YSCALE"));
6962 		setFillTransparency(is->getDouble("CI_FILLT"));
6963 		setLineTransparency(is->getDouble("CI_LINET"));
6964 
6965 		select();
6966 		m_Doc->updatePic();
6967 	}
6968 	else
6969 		asImageFrame()->clearContents();
6970 }
6971 
6972 
restoreDropLinks(UndoState * state,bool isUndo)6973 void PageItem::restoreDropLinks(UndoState *state, bool isUndo)
6974 {
6975 	if (!isTextFrame())
6976 		return;
6977 	ScItemState<QPair<PageItem*, PageItem*> >* is = dynamic_cast<ScItemState<QPair<PageItem*, PageItem*> >*>(state);
6978 	if (!is)
6979 		qFatal("PageItem::restoreDropLinks: dynamic cast failed");
6980 	if (isUndo)
6981 	{
6982 		PageItem* prev = is->getItem().first;
6983 		PageItem* next = is->getItem().second;
6984 
6985 		m_backBox = prev;
6986 		m_nextBox = next;
6987 		invalid = true;
6988 
6989 		if (prev)
6990 		{
6991 			this->itemText  = prev->itemText;
6992 			this->isAutoText |= prev->isAutoText;
6993 			prev->m_nextBox = this;
6994 			while (prev)
6995 			{
6996 				prev->invalid = true;
6997 				prev = prev->m_backBox;
6998 			}
6999 		}
7000 		if (next)
7001 		{
7002 			this->itemText = next->itemText;
7003 			this->isAutoText |= next->isAutoText;
7004 
7005 			next->m_backBox = this;
7006 			while (next)
7007 			{
7008 				next->invalid = true;
7009 				next = next->m_nextBox;
7010 			}
7011 		}
7012 
7013 		// update auto pointers
7014 		if (isAutoText && m_nextBox == nullptr)
7015 		{
7016 			m_Doc->LastAuto = this;
7017 		}
7018 		if (isAutoText && m_backBox == nullptr)
7019 		{
7020 			m_Doc->FirstAuto = this;
7021 		}
7022 	}
7023 	else
7024 	{
7025 		dropLinks();
7026 	}
7027 }
7028 
restoreLinkTextFrame(UndoState * state,bool isUndo)7029 void PageItem::restoreLinkTextFrame(UndoState *state, bool isUndo)
7030 {
7031 	if (!isTextFrame())
7032 		return;
7033 	if (isUndo)
7034 	{
7035 		unlink(false);
7036 		//restore properly text if frame was linked at beginning of chain
7037 		ScItemState<QPair<PageItem*, PageItem*> > *is = dynamic_cast<ScItemState<QPair<PageItem*, PageItem*> >*>(state);
7038 		if (!is)
7039 			qFatal("PageItem::restoreLinkTextFrame 1: dynamic cast failed");
7040 		int joinPos = is->getInt("JOIN_POS");
7041 		int parSep = is->getBool("ADDPARSEP") ? 1 : 0;
7042 		if (is->getBool("FIRST"))
7043 		{
7044 			if (joinPos == 0)
7045 			{
7046 				is->getItem().second->itemText.append(itemText);
7047 				itemText.select(0, itemText.length());
7048 				itemText.removeSelection();
7049 			}
7050 			else
7051 			{
7052 				StoryText content(m_Doc);
7053 				itemText.select(joinPos + parSep, itemText.length() - (joinPos + parSep));
7054 				content.insert(0, itemText, true);
7055 				if (parSep)
7056 					itemText.select(joinPos, itemText.length() - joinPos);
7057 				itemText.removeSelection();
7058 				is->getItem().second->itemText.append(content);
7059 			}
7060 		}
7061 		else
7062 		{
7063 			StoryText content(m_Doc);
7064 			PageItem* prev = is->getItem().second;
7065 			prev->itemText.select(joinPos + parSep, prev->itemText.length() - (joinPos + parSep));
7066 			content.insert(0, prev->itemText, true);
7067 			if (parSep)
7068 				prev->itemText.select(joinPos, prev->itemText.length() - joinPos);
7069 			prev->itemText.removeSelection();
7070 			itemText.append(content);
7071 		}
7072 	}
7073 	else
7074 	{
7075 		ScItemState<QPair<PageItem*, PageItem*> > *is = dynamic_cast<ScItemState<QPair<PageItem*, PageItem*> >*>(state);
7076 		if (!is)
7077 			qFatal("PageItem::restoreLinkTextFrame 2: dynamic cast failed");
7078 		asTextFrame()->link(is->getItem().second->asTextFrame());
7079 	}
7080 }
7081 
restoreUnlinkTextFrame(UndoState * state,bool isUndo)7082 void PageItem::restoreUnlinkTextFrame(UndoState *state, bool isUndo)
7083 {
7084 	if (!isTextFrame())
7085 		return;
7086 	ScItemState<QPair<PageItem*, PageItem*> >* is = dynamic_cast<ScItemState<QPair<PageItem*, PageItem*> >*>(state);
7087 	if (!is)
7088 		qFatal("PageItem::restoreUnlinkTextFrame: dynamic cast failed");
7089 	if (is->contains("CUT_TEXT"))
7090 	{
7091 		if (isUndo)
7092 		{
7093 			PageItem* prev = is->getItem().first;
7094 			PageItem* next  = is->getItem().second;
7095 			if (prev != nullptr)
7096 				prev->link(this, false);
7097 			else if (next != nullptr)
7098 				this->link(next, false);
7099 			else
7100 				Q_ASSERT(prev || next);
7101 		}
7102 		else
7103 			unlinkWithText();
7104 	}
7105 	else
7106 	{
7107 		if (isUndo)
7108 			asTextFrame()->link(is->getItem().second->asTextFrame());
7109 		else
7110 			unlink();
7111 	}
7112 }
7113 
restoreVerticalAlign(SimpleState * ss,bool isUndo)7114 void PageItem::restoreVerticalAlign(SimpleState *ss, bool isUndo)
7115 {
7116 	if (isUndo)
7117 		verticalAlign = ss->getInt("OLD_VERTALIGN");
7118 	else
7119 		verticalAlign = ss->getInt("NEW_VERTALIGN");
7120 	update();
7121 }
7122 
restorePathOperation(UndoState * state,bool isUndo)7123 void PageItem::restorePathOperation(UndoState *state, bool isUndo)
7124 {//PATH_OPERATION
7125 	ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >*is = dynamic_cast<ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >*>(state);
7126 	if (!is)
7127 		qFatal("PageItem::restorePathOperation: dynamic cast failed");
7128 
7129 	if (isUndo)
7130 	{
7131 		this->ClipEdited = is->getBool("PATH_OP_OLD_CLIPEDITED");
7132 		this->FrameType = is->getInt("PATH_OP_OLD_FRAMETYPE");
7133 		this->OldB2 = is->getDouble("PATH_OP_OLD_OLDB2");
7134 		this->OldH2 = is->getDouble("PATH_OP_OLD_OLDH2");
7135 		QPair<FPointArray, FPointArray> oldLines = is->getItem().first;
7136 		this->PoLine = oldLines.first;
7137 		this->ContourLine = oldLines.second;
7138 	}
7139 	else
7140 	{
7141 		this->ClipEdited = is->getBool("PATH_OP_NEW_CLIPEDITED");
7142 		this->FrameType = is->getInt("PATH_OP_NEW_FRAMETYPE");
7143 		this->OldB2 = is->getDouble("PATH_OP_NEW_OLDB2");
7144 		this->OldH2 = is->getDouble("PATH_OP_NEW_OLDH2");
7145 		QPair<FPointArray, FPointArray> newLines = is->getItem().second;
7146 		this->PoLine = newLines.first;
7147 		this->ContourLine = newLines.second;
7148 	}
7149 	this->updateClip();
7150 }
7151 
restorePoly(SimpleState * state,bool isUndo,bool isContour)7152 void PageItem::restorePoly(SimpleState *state, bool isUndo, bool isContour)
7153 {
7154 	int mode = state->getInt("MODE");
7155 	int rot  = state->getInt("ROT");
7156 	ScribusView* view = m_Doc->view();
7157 	double scaling = state->getDouble("SCALING");
7158 	bool editContour = m_Doc->nodeEdit.isContourLine();
7159 	m_Doc->nodeEdit.setIsContourLine(isContour);
7160 	select();
7161 	if (isUndo)
7162 	{
7163 		if (mode % 2 != 0 && mode != 0)
7164 			--mode;
7165 		else
7166 			++mode;
7167 		if (mode == 2)
7168 			scaling = (1.0 - (100.0 / (100.0 + scaling))) * 100.0;
7169 		else if (mode == 3)
7170 			scaling = ((100.0 / (100.0 - scaling)) - 1.0) * 100.0;
7171 	}
7172 	view->TransformPoly(mode, rot, scaling);
7173 	m_Doc->nodeEdit.setIsContourLine(editContour);
7174 }
7175 
restoreUniteItem(SimpleState * state,bool isUndo)7176 void PageItem::restoreUniteItem(SimpleState *state, bool isUndo)
7177 {
7178 	ScItemState< QPair<QList<PageItem*>,QList<QTransform> > > *is = dynamic_cast<ScItemState< QPair<QList<PageItem*>,QList<QTransform> > >*>(state);
7179 	if (!is)
7180 		qFatal("PageItem::restoreUniteItem: dynamic cast failed");
7181 
7182 	m_Doc->view()->deselectItems(true);
7183 	if (isUndo)
7184 	{
7185 		int pts = 0;
7186 		select();
7187 		for (int i = 0; i < is->getItem().first.size(); ++i)
7188 		{
7189 			PageItem* myItem = is->getItem().first.at(i);
7190 			myItem->PoLine.map(is->getItem().second.at(i).inverted());
7191 			pts += myItem->PoLine.size();
7192 			pts+=4;
7193 			doc()->m_Selection->addItem(myItem);
7194 		}
7195 		PoLine.resize(PoLine.size()-pts);
7196 		Segments.clear();
7197 		FrameType = is->getInt("FRAMETYPE");
7198 		ClipEdited = is->getBool("CLIPEDITED");
7199 		int oldRotMode = doc()->rotationMode();
7200 		doc()->setRotationMode(0);
7201 		doc()->adjustItemSize(this);
7202 		doc()->setRotationMode(oldRotMode);
7203 	}
7204 	else
7205 	{
7206 		select();
7207 		for (int i = 0; i < is->getItem().first.size(); ++i)
7208 			doc()->view()->selectItem(is->getItem().first.at(i));
7209 		doc()->itemSelection_UniteItems();
7210 		select();
7211 	}
7212 }
7213 
restoreSplitItem(SimpleState * state,bool isUndo)7214 void PageItem::restoreSplitItem(SimpleState *state, bool isUndo)
7215 {
7216 	ScItemState< QList<int> > *is = dynamic_cast<ScItemState< QList<int> >*>(state);
7217 	if (!is)
7218 		qFatal("PageItem::restoreSplitItem: dynamic cast failed");
7219 
7220 	QList<int> itemsList = is->getItem();
7221 	select();
7222 	if (isUndo)
7223 	{
7224 		for (int i = 0; i < itemsList.size(); ++i)
7225 			doc()->view()->selectItem(doc()->Items->at(itemsList.at(i)));
7226 		doc()->itemSelection_UniteItems();
7227 		select();
7228 	}
7229 	else
7230 		doc()->itemSelection_SplitItems();
7231 }
7232 
restoreContourLine(SimpleState * state,bool isUndo)7233 void PageItem::restoreContourLine(SimpleState *state, bool isUndo)
7234 {
7235 	ScItemState<FPointArray> *is = dynamic_cast<ScItemState<FPointArray>*>(state);
7236 	if (!is)
7237 		qFatal("PageItem::restoreContourLine: dynamic cast failed");
7238 	if (isUndo)
7239 		ContourLine = is->getItem();
7240 	else
7241 		ContourLine = PoLine.copy();
7242 	ClipEdited = true;
7243 }
7244 
restoreShapeType(SimpleState * state,bool isUndo)7245 void PageItem::restoreShapeType(SimpleState *state, bool isUndo)
7246 {
7247 	// Store shape info in this form:
7248 	// CHANGE_SHAPE_TYPE - ID of the undo operation
7249 	// OLD_FRAME_TYPE - original frame type
7250 	// NEW_FRAME_TYPE - change of frame type
7251 	// binary QPair<FPointArray, FPointArray> - .first original shape, .second new shape
7252 	ScItemState<QPair<FPointArray,FPointArray> > *is = dynamic_cast<ScItemState<QPair<FPointArray,FPointArray> >*>(state);
7253 	if (!is)
7254 		qFatal("PageItem::restoreShapeType: dynamic cast failed");
7255 	if (isUndo)
7256 	{
7257 		this->FrameType = is->getInt("OLD_FRAME_TYPE");
7258 		this->PoLine = is->getItem().first;
7259 		ClipEdited = !(FrameType == 0 || FrameType == 1);
7260 	}
7261 	else
7262 	{
7263 		this->FrameType = is->getInt("NEW_FRAME_TYPE");
7264 		this->PoLine = is->getItem().second;
7265 		ClipEdited = (FrameType == 0 || FrameType == 1);
7266 	}
7267 	Clip = flattenPath(PoLine,Segments);
7268 }
7269 
restoreLayer(SimpleState * state,bool isUndo)7270 void PageItem::restoreLayer(SimpleState *state, bool isUndo)
7271 {
7272 	ScribusView* view = m_Doc->view();
7273 	setLayer(isUndo ? state->getInt("OLD_LAYER") : state->getInt("NEW_LAYER"));
7274 	view->deselectItems(true);
7275 	m_Doc->regionsChanged()->update(QRectF());
7276 }
7277 
restoreGetImage(UndoState * state,bool isUndo)7278 void PageItem::restoreGetImage(UndoState *state, bool isUndo)
7279 {
7280 	ScItemState<ScImageEffectList> *is = dynamic_cast<ScItemState<ScImageEffectList>*>(state);
7281 	QString fn = is->get("OLD_IMAGE_PATH");
7282 	if (!isUndo)
7283 		fn = is->get("NEW_IMAGE_PATH");
7284 	if (fn.isEmpty())
7285 	{
7286 		Selection tempSelection(this, false);
7287 		tempSelection.addItem(this, true);
7288 		m_Doc->itemSelection_ClearItem(&tempSelection);
7289 		if (isUndo)
7290 		{
7291 			setImageFlippedH(is->getBool("FLIPPH"));
7292 			setImageFlippedV(is->getBool("FLIPPV"));
7293 			setImageScalingMode(is->getBool("SCALING"), is->getBool("ASPECT"));
7294 		}
7295 	}
7296 	else
7297 	{
7298 		loadImage(fn, false);
7299 		if (isUndo)
7300 		{
7301 			//restore old image settings
7302 			effectsInUse = is->getItem();
7303 			setImageFlippedH(is->getBool("FLIPPH"));
7304 			setImageFlippedV(is->getBool("FLIPPV"));
7305 			setImageScalingMode(is->getBool("SCALING"), is->getBool("ASPECT"));
7306 			setImageXOffset(is->getDouble("XOFF"));
7307 			setImageXScale(is->getDouble("XSCALE"));
7308 			setImageYOffset(is->getDouble("YOFF"));
7309 			setImageYScale(is->getDouble("YSCALE"));
7310 			setFillTransparency(is->getDouble("FILLT"));
7311 			setLineTransparency(is->getDouble("LINET"));
7312 		}
7313 		select();
7314 		m_Doc->updatePic();
7315 	}
7316 }
7317 
restoreShapeContour(UndoState * state,bool isUndo)7318 void PageItem::restoreShapeContour(UndoState *state, bool isUndo)
7319 {
7320 	auto *istate = dynamic_cast<ScItemState<QPair<FPointArray,FPointArray> >*>(state);
7321 	if (istate)
7322 	{
7323 		FPointArray oldClip = istate->getItem().first;
7324 		FPointArray newClip = istate->getItem().second;
7325 		bool isContour = istate->getBool("IS_CONTOUR");
7326 		double oldX = istate->getDouble("OLD_X");
7327 		double oldY = istate->getDouble("OLD_Y");
7328 		double newX = istate->getDouble("NEW_X");
7329 		double newY = istate->getDouble("NEW_Y");
7330 
7331 		if (isUndo)
7332 		{
7333 			if (isContour)
7334 				ContourLine = oldClip;
7335 			else
7336 				PoLine = oldClip;
7337 			m_Doc->adjustItemSize(this);
7338 			m_Doc->moveItem(oldX - xPos(), oldY - yPos(), this);
7339 		}
7340 		else
7341 		{
7342 			if (isContour)
7343 				ContourLine = newClip;
7344 			else
7345 				PoLine = newClip;
7346 			m_Doc->adjustItemSize(this);
7347 			m_Doc->moveItem(newX - xPos(), newY - yPos(), this);
7348 		}
7349 		if (oldClip.count() != newClip.count())
7350 			m_Doc->nodeEdit.deselect();
7351 		m_Doc->regionsChanged()->update(QRectF());
7352 	}
7353 }
7354 
restoreImageEffects(UndoState * state,bool isUndo)7355 void PageItem::restoreImageEffects(UndoState *state, bool isUndo)
7356 {
7357 	auto *istate = dynamic_cast<ScItemState<QPair<ScImageEffectList,ScImageEffectList> >*>(state);
7358 	if (istate)
7359 	{
7360 		if (isUndo)
7361 			effectsInUse = istate->getItem().first;
7362 		else
7363 			effectsInUse = istate->getItem().second;
7364 
7365 		select();
7366 		m_Doc->updatePic();
7367 	}
7368 }
7369 
select()7370 void PageItem::select()
7371 {
7372 	m_Doc->view()->deselectItems(false);
7373 	//CB #2969 add this true parm to addItem so we don't connectToGUI, the rest of view->SelectItem isn't needed anyway
7374 	m_Doc->m_Selection->addItem(this, true);
7375 }
7376 
getObjectAttributes()7377 ObjAttrVector* PageItem::getObjectAttributes()
7378 {
7379 	return &pageItemAttributes;
7380 }
7381 
getObjectAttributes(const QString & attributeName) const7382 QList<ObjectAttribute> PageItem::getObjectAttributes(const QString& attributeName) const
7383 {
7384 	QList<ObjectAttribute> attributes;
7385 	for (ObjAttrVector::const_iterator objAttrIt = pageItemAttributes.begin() ; objAttrIt != pageItemAttributes.end(); ++objAttrIt)
7386 	{
7387 		if (objAttrIt->name == attributeName)
7388 			attributes.append(*objAttrIt);
7389 	}
7390 	return attributes;
7391 }
7392 
getObjectAttribute(const QString & attributeName) const7393 ObjectAttribute PageItem::getObjectAttribute(const QString& attributeName) const
7394 {
7395 	int countFound = 0;
7396 	ObjAttrVector::const_iterator foundIt = pageItemAttributes.begin();
7397 	for (ObjAttrVector::const_iterator objAttrIt = pageItemAttributes.begin(); objAttrIt != pageItemAttributes.end(); ++objAttrIt)
7398 	{
7399 		if (objAttrIt->name == attributeName)
7400 		{
7401 			++countFound;
7402 			foundIt=objAttrIt;
7403 		}
7404 	}
7405 	ObjectAttribute returnAttribute;
7406 	if (countFound==1)
7407 		returnAttribute = (*foundIt);
7408 	else
7409 		returnAttribute.name.clear();
7410 	return returnAttribute;
7411 }
7412 
7413 
setObjectAttributes(ObjAttrVector * map)7414 void PageItem::setObjectAttributes(ObjAttrVector* map)
7415 {
7416 	pageItemAttributes = *map;
7417 }
7418 
7419 //if not `prependCopy` then string "Copy of" wil not be prepended
generateUniqueCopyName(const QString & originalName,bool prependCopy) const7420 QString PageItem::generateUniqueCopyName(const QString& originalName, bool prependCopy) const
7421 {
7422 	if (!m_Doc->itemNameExists(originalName))
7423 		return originalName;
7424 
7425 	// Start embellishing the name until we get an acceptable unique name
7426 	// first we prefix `Copy of' if it's not already there
7427 	QString newname(originalName);
7428 	if (prependCopy && !originalName.startsWith( tr("Copy of")))
7429 		newname.prepend( tr("Copy of")+" ");
7430 
7431 	// See if the name prefixed by "Copy of " is free
7432 	if (m_Doc->itemNameExists(newname))
7433 	{
7434 		// Search the string for (number) at the end and capture
7435 		// both the number and the text leading up to it sans brackets.
7436 		//     Copy of fred (5)
7437 		//     ^^^^^^^^^^^^  ^   (where ^ means captured)
7438 		static QRegExp rx("^(.*)\\s+\\((\\d+)\\)$");
7439 		int numMatches = rx.lastIndexIn(newname);
7440 		// Add a (number) suffix to the end of the name. We start at the
7441 		// old suffix's value if there was one, or at 2 if there was not.
7442 		int suffixnum = 2;
7443 		QString prefix(newname);
7444 		if (numMatches != -1)
7445 		{
7446 			// Already had a suffix; use the name w/o suffix for prefix and
7447 			// grab the old suffix value as a starting point.
7448 			QStringList matches = rx.capturedTexts();
7449 			prefix = matches[1];
7450 			suffixnum = matches[2].toInt();
7451 		}
7452 		// Keep on incrementing the suffix 'till we find a free name
7453 		do
7454 		{
7455 			newname = prefix + " (" + QString::number(suffixnum) + ")";
7456 			suffixnum ++;
7457 		}
7458 		while (m_Doc->itemNameExists(newname));
7459 	}
7460 	// Unnecessary assert, previous code ensure condition is always true - JG
7461 	// assert(!m_Doc->itemNameExists(newname));
7462 	return newname;
7463 }
7464 
replaceNamedResources(ResourceCollection & newNames)7465 void PageItem::replaceNamedResources(ResourceCollection& newNames)
7466 {
7467 	QMap<QString, QString>::ConstIterator it;
7468 
7469 	it = newNames.colors().find(softShadowColor());
7470 	if (it != newNames.colors().end())
7471 		setSoftShadowColor(*it);
7472 
7473 	it = newNames.colors().find(fillColor());
7474 	if (it != newNames.colors().end())
7475 		setFillColor(*it);
7476 
7477 	it = newNames.colors().find(lineColor());
7478 	if (it != newNames.colors().end())
7479 		setLineColor(*it);
7480 
7481 	it = newNames.colors().find(GrColorP1);
7482 	if (it != newNames.colors().end())
7483 		GrColorP1 = *it;
7484 	it = newNames.colors().find(GrColorP2);
7485 	if (it != newNames.colors().end())
7486 		GrColorP2 = *it;
7487 	it = newNames.colors().find(GrColorP3);
7488 	if (it != newNames.colors().end())
7489 		GrColorP3 = *it;
7490 	it = newNames.colors().find(GrColorP4);
7491 	if (it != newNames.colors().end())
7492 		GrColorP4 = *it;
7493 
7494 	QList<VColorStop*> cstops = fill_gradient.colorStops();
7495 	for (int cst = 0; cst < fill_gradient.stops(); ++cst)
7496 	{
7497 		it = newNames.colors().find(cstops.at(cst)->name);
7498 		if (it != newNames.colors().end())
7499 		{
7500 			if (*it != CommonStrings::None)
7501 				cstops.at(cst)->name = *it;
7502 		}
7503 	}
7504 	for (int grow = 0; grow < meshGradientArray.count(); grow++)
7505 	{
7506 		for (int gcol = 0; gcol < meshGradientArray[grow].count(); gcol++)
7507 		{
7508 			MeshPoint mp = meshGradientArray[grow][gcol];
7509 			it = newNames.colors().find(mp.colorName);
7510 			if (it != newNames.colors().end())
7511 				meshGradientArray[grow][gcol].colorName = *it;
7512 		}
7513 	}
7514 	for (int col = 0; col < meshGradientPatches.count(); col++)
7515 	{
7516 		it = newNames.colors().find(meshGradientPatches[col].TL.colorName);
7517 		if (it != newNames.colors().end())
7518 			meshGradientPatches[col].TL.colorName = *it;
7519 		it = newNames.colors().find(meshGradientPatches[col].TR.colorName);
7520 		if (it != newNames.colors().end())
7521 			meshGradientPatches[col].TR.colorName = *it;
7522 		it = newNames.colors().find(meshGradientPatches[col].BL.colorName);
7523 		if (it != newNames.colors().end())
7524 			meshGradientPatches[col].BL.colorName = *it;
7525 		it = newNames.colors().find(meshGradientPatches[col].BR.colorName);
7526 		if (it != newNames.colors().end())
7527 			meshGradientPatches[col].BR.colorName = *it;
7528 	}
7529 	cstops = stroke_gradient.colorStops();
7530 	for (int cst = 0; cst < stroke_gradient.stops(); ++cst)
7531 	{
7532 		it = newNames.colors().find(cstops.at(cst)->name);
7533 		if (it != newNames.colors().end())
7534 		{
7535 			if (*it != CommonStrings::None)
7536 				cstops.at(cst)->name = *it;
7537 		}
7538 	}
7539 	cstops = mask_gradient.colorStops();
7540 	for (int cst = 0; cst < mask_gradient.stops(); ++cst)
7541 	{
7542 		it = newNames.colors().find(cstops.at(cst)->name);
7543 		if (it != newNames.colors().end())
7544 		{
7545 			if (*it != CommonStrings::None)
7546 				cstops.at(cst)->name = *it;
7547 		}
7548 	}
7549 	if (effectsInUse.count() != 0)
7550 	{
7551 		QString col1 = CommonStrings::None;
7552 		QString col2 = CommonStrings::None;
7553 		QString col3 = CommonStrings::None;
7554 		QString col4 = CommonStrings::None;
7555 		for (int a = 0; a < effectsInUse.count(); ++a)
7556 		{
7557 			QString tmpstr = effectsInUse.at(a).effectParameters;
7558 			QString tmpstr2 = "";
7559 			ScTextStream fp(&tmpstr, QIODevice::ReadOnly);
7560 			switch (effectsInUse.at(a).effectCode)
7561 			{
7562 				case ImageEffect::EF_QUADTONE:
7563 					col1 = fp.readLine();
7564 					col2 = fp.readLine();
7565 					col3 = fp.readLine();
7566 					col4 = fp.readLine();
7567 					it = newNames.colors().find(col1);
7568 					if (it != newNames.colors().end())
7569 					{
7570 						if (*it != CommonStrings::None)
7571 							tmpstr2 += *it + "\n";
7572 						else
7573 							tmpstr2 += col1 + "\n";
7574 					}
7575 					else
7576 						tmpstr2 += col1 + "\n";
7577 					it = newNames.colors().find(col2);
7578 					if (it != newNames.colors().end())
7579 					{
7580 						if (*it != CommonStrings::None)
7581 							tmpstr2 += *it + "\n";
7582 						else
7583 							tmpstr2 += col2 + "\n";
7584 					}
7585 					else
7586 						tmpstr2 += col2 + "\n";
7587 					it = newNames.colors().find(col3);
7588 					if (it != newNames.colors().end())
7589 					{
7590 						if (*it != CommonStrings::None)
7591 							tmpstr2 += *it + "\n";
7592 						else
7593 							tmpstr2 += col3 + "\n";
7594 					}
7595 					else
7596 						tmpstr2 += col3 + "\n";
7597 					it = newNames.colors().find(col4);
7598 					if (it != newNames.colors().end())
7599 					{
7600 						if (*it != CommonStrings::None)
7601 							tmpstr2 += *it + "\n";
7602 						else
7603 							tmpstr2 += col4 + "\n";
7604 					}
7605 					else
7606 						tmpstr2 += col4 + "\n";
7607 					tmpstr2 += fp.readAll();
7608 					break;
7609 				case ImageEffect::EF_TRITONE:
7610 					col1 = fp.readLine();
7611 					col2 = fp.readLine();
7612 					col3 = fp.readLine();
7613 					it = newNames.colors().find(col1);
7614 					if (it != newNames.colors().end())
7615 					{
7616 						if (*it != CommonStrings::None)
7617 							tmpstr2 += *it + "\n";
7618 						else
7619 							tmpstr2 += col1 + "\n";
7620 					}
7621 					else
7622 						tmpstr2 += col1 + "\n";
7623 					it = newNames.colors().find(col2);
7624 					if (it != newNames.colors().end())
7625 					{
7626 						if (*it != CommonStrings::None)
7627 							tmpstr2 += *it + "\n";
7628 						else
7629 							tmpstr2 += col2 + "\n";
7630 					}
7631 					else
7632 						tmpstr2 += col2 + "\n";
7633 					it = newNames.colors().find(col3);
7634 					if (it != newNames.colors().end())
7635 					{
7636 						if (*it != CommonStrings::None)
7637 							tmpstr2 += *it + "\n";
7638 						else
7639 							tmpstr2 += col3 + "\n";
7640 					}
7641 					else
7642 						tmpstr2 += col3 + "\n";
7643 					tmpstr2 += fp.readAll();
7644 					break;
7645 				case ImageEffect::EF_DUOTONE:
7646 					col1 = fp.readLine();
7647 					col2 = fp.readLine();
7648 					it = newNames.colors().find(col1);
7649 					if (it != newNames.colors().end())
7650 					{
7651 						if (*it != CommonStrings::None)
7652 							tmpstr2 += *it + "\n";
7653 						else
7654 							tmpstr2 += col1 + "\n";
7655 					}
7656 					else
7657 						tmpstr2 += col1 + "\n";
7658 					it = newNames.colors().find(col2);
7659 					if (it != newNames.colors().end())
7660 					{
7661 						if (*it != CommonStrings::None)
7662 							tmpstr2 += *it + "\n";
7663 						else
7664 							tmpstr2 += col2 + "\n";
7665 					}
7666 					else
7667 						tmpstr2 += col2 + "\n";
7668 					tmpstr2 += fp.readAll();
7669 					break;
7670 				case ImageEffect::EF_COLORIZE:
7671 					col1 = fp.readLine();
7672 					it = newNames.colors().find(col1);
7673 					if (it != newNames.colors().end())
7674 					{
7675 						if (*it != CommonStrings::None)
7676 							tmpstr2 += *it + "\n" + fp.readAll();
7677 						else
7678 							tmpstr2 += col1 + "\n" + fp.readAll();
7679 					}
7680 					else
7681 						tmpstr2 += col1 + "\n" + fp.readAll();
7682 					break;
7683 				default:
7684 					tmpstr2 = tmpstr;
7685 					break;
7686 			}
7687 			effectsInUse[a].effectParameters = tmpstr2;
7688 		}
7689 	}
7690 
7691 	it = newNames.patterns().find(pattern());
7692 	if (it != newNames.patterns().end())
7693 		setPattern(*it);
7694 
7695 	it = newNames.patterns().find(strokePattern());
7696 	if (it != newNames.patterns().end())
7697 		setStrokePattern(*it);
7698 	it = newNames.patterns().find(patternMask());
7699 	if (it != newNames.patterns().end())
7700 		setPatternMask(*it);
7701 
7702 	it = newNames.gradients().find(strokeGradient());
7703 	if (it != newNames.gradients().end())
7704 		setStrokeGradient(*it);
7705 
7706 	it = newNames.gradients().find(gradient());
7707 	if (it != newNames.gradients().end())
7708 		setGradient(*it);
7709 	it = newNames.gradients().find(gradientMask());
7710 	if (it != newNames.gradients().end())
7711 		setGradientMask(*it);
7712 
7713 	it = newNames.lineStyles().find(customLineStyle());
7714 	if (it != newNames.lineStyles().end())
7715 		setCustomLineStyle(*it);
7716 
7717 	if (prevInChain() == nullptr)
7718 		itemText.replaceNamedResources(newNames);
7719 }
7720 
setGradientType(int val)7721 void PageItem::setGradientType(int val)
7722 {
7723 	if (GrType == val)
7724 		return;
7725 	if (UndoManager::undoEnabled())
7726 	{
7727 		SimpleState *ss = new SimpleState(Um::GradType, QString(), Um::IFill);
7728 		ss->set("GRAD_TYPE");
7729 		ss->set("OLD", GrType);
7730 		ss->set("NEW", val);
7731 		undoManager->action(this, ss);
7732 	}
7733 	GrType = val;
7734 }
7735 
setStrokeGradientType(int val)7736 void PageItem::setStrokeGradientType(int val)
7737 {
7738 	if (GrTypeStroke == val)
7739 		return;
7740 	if (UndoManager::undoEnabled())
7741 	{
7742 		SimpleState *ss = new SimpleState(Um::GradTypeStroke, QString(), Um::ILineStyle);
7743 		ss->set("GRAD_TYPESTROKE");
7744 		ss->set("OLD", GrTypeStroke);
7745 		ss->set("NEW", val);
7746 		undoManager->action(this, ss);
7747 	}
7748 	GrTypeStroke = val;
7749 }
7750 
setGradientCol1(const QString & val)7751 void PageItem::setGradientCol1(const QString& val)
7752 {
7753 	if (GrColorP1 == val)
7754 		return;
7755 	if (UndoManager::undoEnabled())
7756 	{
7757 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7758 		ss->set("GRAD_COL1");
7759 		ss->set("OLD", GrColorP1);
7760 		ss->set("NEW", val);
7761 		undoManager->action(this, ss);
7762 	}
7763 	GrColorP1 = val;
7764 }
7765 
setGradientCol2(const QString & val)7766 void PageItem::setGradientCol2(const QString& val)
7767 {
7768 	if (GrColorP2 == val)
7769 		return;
7770 	if (UndoManager::undoEnabled())
7771 	{
7772 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7773 		ss->set("GRAD_COL2");
7774 		ss->set("OLD", GrColorP2);
7775 		ss->set("NEW", val);
7776 		undoManager->action(this, ss);
7777 	}
7778 	GrColorP2 = val;
7779 }
7780 
setGradientCol3(const QString & val)7781 void PageItem::setGradientCol3(const QString& val)
7782 {
7783 	if (GrColorP3 == val)
7784 		return;
7785 	if (UndoManager::undoEnabled())
7786 	{
7787 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7788 		ss->set("GRAD_COL3");
7789 		ss->set("OLD", GrColorP3);
7790 		ss->set("NEW", val);
7791 		undoManager->action(this, ss);
7792 	}
7793 	GrColorP3 = val;
7794 }
7795 
setGradientCol4(const QString & val)7796 void PageItem::setGradientCol4(const QString& val)
7797 {
7798 	if (GrColorP4 == val)
7799 		return;
7800 	if (UndoManager::undoEnabled())
7801 	{
7802 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7803 		ss->set("GRAD_COL4");
7804 		ss->set("OLD", GrColorP4);
7805 		ss->set("NEW", val);
7806 		undoManager->action(this, ss);
7807 	}
7808 	GrColorP4 = val;
7809 }
7810 
setGradientShade1(int val)7811 void PageItem::setGradientShade1(int val)
7812 {
7813 	if (GrCol1Shade == val)
7814 		return;
7815 	if (UndoManager::undoEnabled())
7816 	{
7817 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7818 		ss->set("GRAD_SHADE1");
7819 		ss->set("OLD", GrCol1Shade);
7820 		ss->set("NEW", val);
7821 		undoManager->action(this, ss);
7822 	}
7823 	GrCol1Shade = val;
7824 }
7825 
setGradientShade2(int val)7826 void PageItem::setGradientShade2(int val)
7827 {
7828 	if (GrCol2Shade == val)
7829 		return;
7830 	if (UndoManager::undoEnabled())
7831 	{
7832 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7833 		ss->set("GRAD_SHADE2");
7834 		ss->set("OLD", GrCol2Shade);
7835 		ss->set("NEW", val);
7836 		undoManager->action(this, ss);
7837 	}
7838 	GrCol2Shade = val;
7839 }
7840 
setGradientShade3(int val)7841 void PageItem::setGradientShade3(int val)
7842 {
7843 	if (GrCol3Shade == val)
7844 		return;
7845 	if (UndoManager::undoEnabled())
7846 	{
7847 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7848 		ss->set("GRAD_SHADE3");
7849 		ss->set("OLD", GrCol3Shade);
7850 		ss->set("NEW", val);
7851 		undoManager->action(this, ss);
7852 	}
7853 	GrCol3Shade = val;
7854 }
7855 
setGradientShade4(int val)7856 void PageItem::setGradientShade4(int val)
7857 {
7858 	if (GrCol4Shade == val)
7859 		return;
7860 	if (UndoManager::undoEnabled())
7861 	{
7862 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7863 		ss->set("GRAD_SHADE4");
7864 		ss->set("OLD", GrCol4Shade);
7865 		ss->set("NEW", val);
7866 		undoManager->action(this, ss);
7867 	}
7868 	GrCol4Shade = val;
7869 }
7870 
setGradientTransp1(double val)7871 void PageItem::setGradientTransp1(double val)
7872 {
7873 	if (GrCol1transp == val)
7874 		return;
7875 	if (UndoManager::undoEnabled())
7876 	{
7877 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7878 		ss->set("GRAD_TRANSP1");
7879 		ss->set("OLD", GrCol1transp);
7880 		ss->set("NEW", val);
7881 		undoManager->action(this, ss);
7882 	}
7883 	GrCol1transp = val;
7884 }
7885 
setGradientTransp2(double val)7886 void PageItem::setGradientTransp2(double val)
7887 {
7888 	if (GrCol2transp == val)
7889 		return;
7890 	if (UndoManager::undoEnabled())
7891 	{
7892 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7893 		ss->set("GRAD_TRANSP2");
7894 		ss->set("OLD", GrCol2transp);
7895 		ss->set("NEW", val);
7896 		undoManager->action(this, ss);
7897 	}
7898 	GrCol2transp = val;
7899 }
7900 
setGradientTransp3(double val)7901 void PageItem::setGradientTransp3(double val)
7902 {
7903 	if (GrCol3transp == val)
7904 		return;
7905 	if (UndoManager::undoEnabled())
7906 	{
7907 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7908 		ss->set("GRAD_TRANSP3");
7909 		ss->set("OLD", GrCol3transp);
7910 		ss->set("NEW", val);
7911 		undoManager->action(this, ss);
7912 	}
7913 	GrCol3transp = val;
7914 }
7915 
setGradientTransp4(double val)7916 void PageItem::setGradientTransp4(double val)
7917 {
7918 	if (GrCol4transp == val)
7919 		return;
7920 	if (UndoManager::undoEnabled())
7921 	{
7922 		SimpleState *ss = new SimpleState(Um::GradCol, QString(), Um::IFill);
7923 		ss->set("GRAD_TRANSP4");
7924 		ss->set("OLD", GrCol4transp);
7925 		ss->set("NEW", val);
7926 		undoManager->action(this, ss);
7927 	}
7928 	GrCol4transp = val;
7929 }
7930 
setGradientColor1(const QColor & val)7931 void PageItem::setGradientColor1(const QColor& val)
7932 {
7933 	if (m_grQColorP1 == val)
7934 		return;
7935 	if (UndoManager::undoEnabled())
7936 	{
7937 		ScItemState<QPair<QColor,QColor> > *ss = new ScItemState<QPair<QColor,QColor> >(Um::GradCol, QString(), Um::IFill);
7938 		ss->set("GRAD_QCOLOR1");
7939 		ss->setItem(qMakePair(m_grQColorP1, val));
7940 		undoManager->action(this, ss);
7941 	}
7942 	m_grQColorP1 = val;
7943 }
7944 
setGradientColor2(const QColor & val)7945 void PageItem::setGradientColor2(const QColor& val)
7946 {
7947 	if (m_grQColorP2 == val)
7948 		return;
7949 	if (UndoManager::undoEnabled())
7950 	{
7951 		ScItemState<QPair<QColor,QColor> > *ss = new ScItemState<QPair<QColor,QColor> >(Um::GradCol, QString(), Um::IFill);
7952 		ss->set("GRAD_QCOLOR2");
7953 		ss->setItem(qMakePair(m_grQColorP2, val));
7954 		undoManager->action(this, ss);
7955 	}
7956 	m_grQColorP2 = val;
7957 }
7958 
setGradientColor3(const QColor & val)7959 void PageItem::setGradientColor3(const QColor& val)
7960 {
7961 	if (m_grQColorP3 == val)
7962 		return;
7963 	if (UndoManager::undoEnabled())
7964 	{
7965 		ScItemState<QPair<QColor,QColor> > *ss = new ScItemState<QPair<QColor,QColor> >(Um::GradCol, QString(), Um::IFill);
7966 		ss->set("GRAD_QCOLOR3");
7967 		ss->setItem(qMakePair(m_grQColorP3, val));
7968 		undoManager->action(this, ss);
7969 	}
7970 	m_grQColorP3 = val;
7971 }
7972 
setGradientColor4(const QColor & val)7973 void PageItem::setGradientColor4(const QColor& val)
7974 {
7975 	if (m_grQColorP4 == val)
7976 		return;
7977 	if (UndoManager::undoEnabled())
7978 	{
7979 		ScItemState<QPair<QColor,QColor> > *ss = new ScItemState<QPair<QColor,QColor> >(Um::GradCol, QString(), Um::IFill);
7980 		ss->set("GRAD_QCOLOR4");
7981 		ss->setItem(qMakePair(m_grQColorP4, val));
7982 		undoManager->action(this, ss);
7983 	}
7984 	m_grQColorP4 = val;
7985 }
7986 
setGradientExtend(VGradient::VGradientRepeatMethod val)7987 void PageItem::setGradientExtend(VGradient::VGradientRepeatMethod val)
7988 {
7989 	GrExtend = val;
7990 }
7991 
setStrokeGradientExtend(VGradient::VGradientRepeatMethod val)7992 void PageItem::setStrokeGradientExtend(VGradient::VGradientRepeatMethod val)
7993 {
7994 	GrStrokeExtend = val;
7995 }
7996 
getGradientExtend()7997 VGradient::VGradientRepeatMethod PageItem::getGradientExtend()
7998 {
7999 	return GrExtend;
8000 }
8001 
getStrokeGradientExtend()8002 VGradient::VGradientRepeatMethod PageItem::getStrokeGradientExtend()
8003 {
8004 	return GrStrokeExtend;
8005 }
8006 
8007 
setSnapToPatchGrid(bool val)8008 void PageItem::setSnapToPatchGrid(bool val)
8009 {
8010 	if (snapToPatchGrid == val)
8011 		return;
8012 	if (UndoManager::undoEnabled())
8013 	{
8014 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8015 		ss->set("SNAP_TO_PATCH");
8016 		ss->set("OLD", val);
8017 		undoManager->action(this, ss);
8018 	}
8019 	snapToPatchGrid = val;
8020 }
8021 
setGradientStart(double x,double y)8022 void PageItem::setGradientStart(double x, double y)
8023 {
8024 	if ((GrStartX == x) && (GrStartY == y))
8025 		return;
8026 	if (UndoManager::undoEnabled())
8027 	{
8028 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8029 		ss->set("GRAD_START");
8030 		ss->set("OLDX", GrStartX);
8031 		ss->set("OLDY", GrStartY);
8032 		ss->set("NEWX", x);
8033 		ss->set("NEWY", y);
8034 		undoManager->action(this, ss);
8035 	}
8036 	GrStartX = x;
8037 	GrStartY = y;
8038 }
8039 
setGradientEnd(double x,double y)8040 void PageItem::setGradientEnd(double x, double y)
8041 {
8042 	if ((GrEndX == x) && (GrEndY == y))
8043 		return;
8044 	if (UndoManager::undoEnabled())
8045 	{
8046 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8047 		ss->set("GRAD_END");
8048 		ss->set("OLDX", GrEndX);
8049 		ss->set("OLDY", GrEndY);
8050 		ss->set("NEWX", x);
8051 		ss->set("NEWY", y);
8052 		undoManager->action(this, ss);
8053 	}
8054 	GrEndX = x;
8055 	GrEndY = y;
8056 }
8057 
setGradientFocal(double x,double y)8058 void PageItem::setGradientFocal(double x, double y)
8059 {
8060 	if ((GrFocalX == x) && (GrFocalY == y))
8061 		return;
8062 	if (UndoManager::undoEnabled())
8063 	{
8064 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8065 		ss->set("GRAD_FOCAL");
8066 		ss->set("OLDX", GrFocalX);
8067 		ss->set("OLDY", GrFocalY);
8068 		ss->set("NEWX", x);
8069 		ss->set("NEWY", y);
8070 		undoManager->action(this, ss);
8071 	}
8072 	GrFocalX = x;
8073 	GrFocalY = y;
8074 }
8075 
setGradientScale(double val)8076 void PageItem::setGradientScale(double val)
8077 {
8078 	if (GrScale == val)
8079 		return;
8080 	if (UndoManager::undoEnabled())
8081 	{
8082 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8083 		ss->set("GRAD_SCALE");
8084 		ss->set("OLD", GrScale);
8085 		ss->set("NEW", val);
8086 		undoManager->action(this, ss);
8087 	}
8088 	GrScale = val;
8089 }
8090 
setGradientSkew(double val)8091 void PageItem::setGradientSkew(double val)
8092 {
8093 	if (GrSkew == val)
8094 		return;
8095 	if (UndoManager::undoEnabled())
8096 	{
8097 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8098 		ss->set("GRAD_SKEW");
8099 		ss->set("OLD", GrSkew);
8100 		ss->set("NEW", val);
8101 		undoManager->action(this, ss);
8102 	}
8103 	GrSkew = val;
8104 }
8105 
setGradientMaskStart(double x,double y)8106 void PageItem::setGradientMaskStart(double x, double y)
8107 {
8108 	if ((GrMaskStartX == x) && (GrMaskStartY == y))
8109 		return;
8110 	if (UndoManager::undoEnabled())
8111 	{
8112 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8113 		ss->set("GRAD_MASKSTART");
8114 		ss->set("OLDX", GrMaskStartX);
8115 		ss->set("OLDY", GrMaskStartY);
8116 		ss->set("NEWX", x);
8117 		ss->set("NEWY", y);
8118 		undoManager->action(this, ss);
8119 	}
8120 	GrMaskStartX = x;
8121 	GrMaskStartY = y;
8122 }
8123 
setGradientMaskEnd(double x,double y)8124 void PageItem::setGradientMaskEnd(double x, double y)
8125 {
8126 	if ((GrMaskEndX == x) && (GrMaskEndY == y))
8127 		return;
8128 	if (UndoManager::undoEnabled())
8129 	{
8130 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8131 		ss->set("GRAD_MASKEND");
8132 		ss->set("OLDX", GrMaskEndX);
8133 		ss->set("OLDY", GrMaskEndY);
8134 		ss->set("NEWX", x);
8135 		ss->set("NEWY", y);
8136 		undoManager->action(this, ss);
8137 	}
8138 	GrMaskEndX = x;
8139 	GrMaskEndY = y;
8140 }
8141 
setGradientMaskFocal(double x,double y)8142 void PageItem::setGradientMaskFocal(double x, double y)
8143 {
8144 	if ((GrMaskFocalX == x) && (GrMaskFocalY == y))
8145 		return;
8146 	if (UndoManager::undoEnabled())
8147 	{
8148 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8149 		ss->set("GRAD_MASKFOCAL");
8150 		ss->set("OLDX", GrMaskFocalX);
8151 		ss->set("OLDY", GrMaskFocalY);
8152 		ss->set("NEWX", x);
8153 		ss->set("NEWY", y);
8154 		undoManager->action(this, ss);
8155 	}
8156 	GrMaskFocalX = x;
8157 	GrMaskFocalY = y;
8158 }
8159 
setGradientMaskScale(double val)8160 void PageItem::setGradientMaskScale(double val)
8161 {
8162 	if (GrMaskScale == val)
8163 		return;
8164 	if (UndoManager::undoEnabled())
8165 	{
8166 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8167 		ss->set("GRAD_MASKSCALE");
8168 		ss->set("OLD", GrMaskScale);
8169 		ss->set("NEW", val);
8170 		undoManager->action(this, ss);
8171 	}
8172 	GrMaskScale = val;
8173 }
8174 
setGradientMaskSkew(double val)8175 void PageItem::setGradientMaskSkew(double val)
8176 {
8177 	if (GrMaskSkew == val)
8178 		return;
8179 	if (UndoManager::undoEnabled())
8180 	{
8181 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::IFill);
8182 		ss->set("GRAD_MASKSKEW");
8183 		ss->set("OLD", GrMaskSkew);
8184 		ss->set("NEW", val);
8185 		undoManager->action(this, ss);
8186 	}
8187 	GrMaskSkew = val;
8188 }
8189 
setGradientControl1(const FPoint & val)8190 void PageItem::setGradientControl1(const FPoint& val)
8191 {
8192 	if (GrControl1 == val)
8193 		return;
8194 	if (UndoManager::undoEnabled())
8195 	{
8196 		ScItemState<QPair<FPoint,FPoint> > *ss = new ScItemState<QPair<FPoint,FPoint> >(Um::GradPos, QString(), Um::IFill);
8197 		ss->set("GRAD_CONTROL1");
8198 		ss->setItem(qMakePair(GrControl1, val));
8199 		undoManager->action(this, ss);
8200 	}
8201 	GrControl1 = val;
8202 }
8203 
setGradientControl2(const FPoint & val)8204 void PageItem::setGradientControl2(const FPoint& val)
8205 {
8206 	if (GrControl2 == val)
8207 		return;
8208 	if (UndoManager::undoEnabled())
8209 	{
8210 		ScItemState<QPair<FPoint,FPoint> > *ss = new ScItemState<QPair<FPoint,FPoint> >(Um::GradPos, QString(), Um::IFill);
8211 		ss->set("GRAD_CONTROL2");
8212 		ss->setItem(qMakePair(GrControl2, val));
8213 		undoManager->action(this, ss);
8214 	}
8215 	GrControl2 = val;
8216 }
8217 
setGradientControl3(const FPoint & val)8218 void PageItem::setGradientControl3(const FPoint& val)
8219 {
8220 	if (GrControl3 == val)
8221 		return;
8222 	if (UndoManager::undoEnabled())
8223 	{
8224 		ScItemState<QPair<FPoint,FPoint> > *ss = new ScItemState<QPair<FPoint,FPoint> >(Um::GradPos, QString(), Um::IFill);
8225 		ss->set("GRAD_CONTROL3");
8226 		ss->setItem(qMakePair(GrControl3, val));
8227 		undoManager->action(this, ss);
8228 	}
8229 	GrControl3 = val;
8230 }
8231 
setGradientControl4(const FPoint & val)8232 void PageItem::setGradientControl4(const FPoint& val)
8233 {
8234 	if (GrControl4 == val)
8235 		return;
8236 	if (UndoManager::undoEnabled())
8237 	{
8238 		ScItemState<QPair<FPoint,FPoint> > *ss = new ScItemState<QPair<FPoint,FPoint> >(Um::GradPos, QString(), Um::IFill);
8239 		ss->set("GRAD_CONTROL4");
8240 		ss->setItem(qMakePair(GrControl4, val));
8241 		undoManager->action(this, ss);
8242 	}
8243 	GrControl4 = val;
8244 }
8245 
setGradientControl5(const FPoint & val)8246 void PageItem::setGradientControl5(const FPoint& val)
8247 {
8248 	if (GrControl5 == val)
8249 		return;
8250 	if (UndoManager::undoEnabled())
8251 	{
8252 		ScItemState<QPair<FPoint,FPoint> > *ss = new ScItemState<QPair<FPoint,FPoint> >(Um::GradPos, QString(), Um::IFill);
8253 		ss->set("GRAD_CONTROL5");
8254 		ss->setItem(qMakePair(GrControl5, val));
8255 		undoManager->action(this, ss);
8256 	}
8257 	GrControl5 = val;
8258 }
8259 
setGradientStrokeScale(double val)8260 void PageItem::setGradientStrokeScale(double val)
8261 {
8262 	if (GrStrokeScale == val)
8263 		return;
8264 	if (UndoManager::undoEnabled())
8265 	{
8266 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::ILine);
8267 		ss->set("GRADSTROKE_SCALE");
8268 		ss->set("OLD", GrStrokeScale);
8269 		ss->set("NEW", val);
8270 		undoManager->action(this, ss);
8271 	}
8272 	GrStrokeScale = val;
8273 }
8274 
setGradientStrokeSkew(double val)8275 void PageItem::setGradientStrokeSkew(double val)
8276 {
8277 	if (GrStrokeSkew == val)
8278 		return;
8279 	if (UndoManager::undoEnabled())
8280 	{
8281 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::ILine);
8282 		ss->set("GRADSTROKE_SKEW");
8283 		ss->set("OLD", GrStrokeSkew);
8284 		ss->set("NEW", val);
8285 		undoManager->action(this, ss);
8286 	}
8287 	GrStrokeSkew = val;
8288 }
8289 
setGradientStrokeFocal(double x,double y)8290 void PageItem::setGradientStrokeFocal(double x, double y)
8291 {
8292 	if ((GrStrokeFocalX == x) & (GrStrokeFocalY == y))
8293 		return;
8294 	if (UndoManager::undoEnabled())
8295 	{
8296 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::ILine);
8297 		ss->set("GRADSTROKE_FOCAL");
8298 		ss->set("OLDX", GrStrokeFocalX);
8299 		ss->set("OLDY", GrStrokeFocalY);
8300 		ss->set("NEWX", x);
8301 		ss->set("NEWY", y);
8302 		undoManager->action(this, ss);
8303 	}
8304 	GrStrokeFocalX = x;
8305 	GrStrokeFocalY = y;
8306 }
8307 
setGradientStrokeStart(double x,double y)8308 void PageItem::setGradientStrokeStart(double x, double y)
8309 {
8310 	if ((GrStrokeStartX == x) && (GrStrokeStartY == y))
8311 		return;
8312 	if (UndoManager::undoEnabled())
8313 	{
8314 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::ILine);
8315 		ss->set("GRADSTROKE_START");
8316 		ss->set("OLDX", GrStrokeStartX);
8317 		ss->set("OLDY", GrStrokeStartY);
8318 		ss->set("NEWX", x);
8319 		ss->set("NEWY", y);
8320 		undoManager->action(this, ss);
8321 	}
8322 	GrStrokeStartX = x;
8323 	GrStrokeStartY = y;
8324 }
8325 
setGradientStrokeEnd(double x,double y)8326 void PageItem::setGradientStrokeEnd(double x, double y)
8327 {
8328 	if ((GrStrokeEndX == x) && (GrStrokeEndY == y))
8329 		return;
8330 	if (UndoManager::undoEnabled())
8331 	{
8332 		SimpleState *ss = new SimpleState(Um::GradPos, QString(), Um::ILine);
8333 		ss->set("GRADSTROKE_END");
8334 		ss->set("OLDX", GrStrokeEndX);
8335 		ss->set("OLDY", GrStrokeEndY);
8336 		ss->set("NEWX", x);
8337 		ss->set("NEWY", y);
8338 		undoManager->action(this, ss);
8339 	}
8340 	GrStrokeEndX = x;
8341 	GrStrokeEndY = y;
8342 }
8343 
getNamedResources(ResourceCollection & lists) const8344 void PageItem::getNamedResources(ResourceCollection& lists) const
8345 {
8346 	if (hasSoftShadow())
8347 		lists.collectColor(softShadowColor());
8348 
8349 	if (GrType == 0)
8350 		lists.collectColor(fillColor());
8351 	else if ((GrType < Gradient_Pattern) || (GrType == Gradient_Diamond))
8352 	{
8353 		if ((!m_gradientName.isEmpty()) && (m_Doc->docGradients.contains(m_gradientName)))
8354 			lists.collectGradient(m_gradientName);
8355 		QList<VColorStop*> cstops = fill_gradient.colorStops();
8356 		for (int cst = 0; cst < fill_gradient.stops(); ++cst)
8357 		{
8358 			lists.collectColor(cstops.at(cst)->name);
8359 		}
8360 	}
8361 	else if (GrType == Gradient_4Colors)
8362 	{
8363 		lists.collectColor(GrColorP1);
8364 		lists.collectColor(GrColorP2);
8365 		lists.collectColor(GrColorP3);
8366 		lists.collectColor(GrColorP4);
8367 	}
8368 	else if (GrType == Gradient_Mesh)
8369 	{
8370 		for (int grow = 0; grow < meshGradientArray.count(); grow++)
8371 		{
8372 			for (int gcol = 0; gcol < meshGradientArray[grow].count(); gcol++)
8373 			{
8374 				if (m_Doc->PageColors.contains(meshGradientArray[grow][gcol].colorName))
8375 					lists.collectColor(meshGradientArray[grow][gcol].colorName);
8376 			}
8377 		}
8378 	}
8379 	else if (GrType == Gradient_PatchMesh)
8380 	{
8381 		for (int col = 0; col < meshGradientPatches.count(); col++)
8382 		{
8383 			lists.collectColor(meshGradientPatches[col].TL.colorName);
8384 			lists.collectColor(meshGradientPatches[col].TR.colorName);
8385 			lists.collectColor(meshGradientPatches[col].BL.colorName);
8386 			lists.collectColor(meshGradientPatches[col].BR.colorName);
8387 		}
8388 	}
8389 	if (GrTypeStroke == 0)
8390 		lists.collectColor(lineColor());
8391 	else if (GrTypeStroke < Gradient_Pattern)
8392 	{
8393 		if ((!gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal)))
8394 			lists.collectGradient(gradientStrokeVal);
8395 		QList<VColorStop*> cstops = stroke_gradient.colorStops();
8396 		for (int cst = 0; cst < stroke_gradient.stops(); ++cst)
8397 		{
8398 			lists.collectColor(cstops.at(cst)->name);
8399 		}
8400 	}
8401 	if ((GrMask == GradMask_Linear) || (GrMask == GradMask_Radial) || (GrMask == GradMask_LinearLumAlpha) || (GrMask == GradMask_RadialLumAlpha))
8402 	{
8403 		QList<VColorStop*> cstops = mask_gradient.colorStops();
8404 		for (int cst = 0; cst < mask_gradient.stops(); ++cst)
8405 		{
8406 			lists.collectColor(cstops.at(cst)->name);
8407 		}
8408 	}
8409 	if (effectsInUse.count() != 0)
8410 	{
8411 		for (int a = 0; a < effectsInUse.count(); ++a)
8412 		{
8413 			QString tmpstr = effectsInUse.at(a).effectParameters;
8414 			ScTextStream fp(&tmpstr, QIODevice::ReadOnly);
8415 			switch (effectsInUse.at(a).effectCode)
8416 			{
8417 				case ImageEffect::EF_QUADTONE:
8418 					lists.collectColor(fp.readLine());
8419 				case ImageEffect::EF_TRITONE:
8420 					lists.collectColor(fp.readLine());
8421 				case ImageEffect::EF_DUOTONE:
8422 					lists.collectColor(fp.readLine());
8423 				case ImageEffect::EF_COLORIZE:
8424 					lists.collectColor(fp.readLine());
8425 					break;
8426 				default:
8427 					break;
8428 			}
8429 		}
8430 	}
8431 	lists.collectPattern(pattern());
8432 	lists.collectPattern(strokePattern());
8433 	lists.collectLineStyle(customLineStyle());
8434 	if (prevInChain() == nullptr)
8435 		itemText.getNamedResources(lists);
8436 }
8437 
8438 //Moved from View
SetFrameShape(int count,const double * vals)8439 void PageItem::SetFrameShape(int count, const double *vals)
8440 {
8441 	PoLine.resize(0);
8442 	for (int i = 0; i < count - 3; i += 4)
8443 	{
8444 		if (vals[i] < 0)
8445 		{
8446 			PoLine.setMarker();
8447 			continue;
8448 		}
8449 		double x1 = m_width * vals[i] / 100.0;
8450 		double y1 = m_height * vals[i + 1] / 100.0;
8451 		double x2 = m_width * vals[i + 2] / 100.0;
8452 		double y2 = m_height * vals[i + 3] / 100.0;
8453 		PoLine.addPoint(x1, y1);
8454 		PoLine.addPoint(x2, y2);
8455 	}
8456 	Clip = flattenPath(PoLine, Segments);
8457 	ClipEdited = true;
8458 }
8459 
SetRectFrame()8460 void PageItem::SetRectFrame()
8461 {
8462 	static double rect[] = {  0.0,   0.0,   0.0,   0.0,
8463 							100.0,   0.0, 100.0,   0.0,
8464 							100.0,   0.0, 100.0,   0.0,
8465 							100.0, 100.0, 100.0, 100.0,
8466 							100.0, 100.0, 100.0, 100.0,
8467 							  0.0, 100.0,   0.0, 100.0,
8468 							  0.0, 100.0,   0.0, 100.0,
8469 							  0.0,   0.0,   0.0,   0.0};
8470 	SetFrameShape(32, rect);
8471 	ClipEdited = false;
8472 	FrameType = 0;
8473 }
8474 
SetOvalFrame()8475 void PageItem::SetOvalFrame()
8476 {
8477 	static double rect[] = {   100.0,  50.0, 100.0,       77.615235,
8478 								50.0, 100.0,  77.615235, 100.0,
8479 								50.0, 100.0,  22.385765, 100.0,
8480 								 0.0,  50.0,   0.0,       77.615235,
8481 								 0.0,  50.0,   0.0,       22.385765,
8482 								50.0,   0.0,  22.385765,   0.0,
8483 								50.0,   0.0,  77.615235,   0.0,
8484 							   100.0,  50.0, 100.0,       22.385765};
8485 	SetFrameShape(32, rect);
8486 	FrameType = 1;
8487 	ClipEdited = false;
8488 }
8489 
SetFrameRound()8490 void PageItem::SetFrameRound()
8491 {
8492 	setCornerRadius(qMin(m_roundedCornerRadius, qMin(m_width, m_height)/2));
8493 	PoLine.resize(0);
8494 	double rr = fabs(m_roundedCornerRadius);
8495 	if (m_roundedCornerRadius > 0.0)
8496 	{
8497 		QPainterPath path;
8498 		path.addRoundedRect(0, 0, m_width, m_height, rr, rr);
8499 		PoLine.fromQPainterPath(path);
8500 	}
8501 	else
8502 	{
8503 		double bezierFactor = 0.552284749; //Bezier Control Point Factor: 8/3*(sin(45)-0.5)
8504 		double rrxBezierFactor = rr*bezierFactor;
8505 		double Width_rr = m_width-rr;
8506 		double Height_rr = m_height-rr;
8507 		PoLine.addQuadPoint(rr, 0, rr, 0, Width_rr, 0, Width_rr, 0);
8508 		PoLine.addQuadPoint(Width_rr, 0, Width_rr, rrxBezierFactor, m_width, rr, m_width-rrxBezierFactor, rr);
8509 		PoLine.addQuadPoint(m_width, rr, m_width, rr, m_width, Height_rr, m_width, Height_rr);
8510 		PoLine.addQuadPoint(m_width, Height_rr, m_width-rrxBezierFactor, Height_rr, Width_rr, m_height, Width_rr, m_height-rrxBezierFactor);
8511 		PoLine.addQuadPoint(Width_rr, m_height, Width_rr, m_height, rr, m_height, rr, m_height);
8512 		PoLine.addQuadPoint(rr, m_height, rr, m_height-rrxBezierFactor, 0, Height_rr, rrxBezierFactor, Height_rr);
8513 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
8514 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
8515 	}
8516 	Clip = flattenPath(PoLine, Segments);
8517 	ClipEdited = false;
8518 	FrameType = 2;
8519 }
8520 
getGroupTransform() const8521 QTransform PageItem::getGroupTransform() const
8522 {
8523 	QTransform result;
8524 	result.translate(gXpos, gYpos);
8525 	result.rotate(m_rotation);
8526 	return result;
8527 }
8528 
getTransform(QTransform & mat) const8529 void PageItem::getTransform(QTransform& mat) const
8530 {
8531 	mat.translate(m_xPos, m_yPos);
8532 	mat.rotate(m_rotation);
8533 }
8534 
getTransform() const8535 QTransform PageItem::getTransform() const
8536 {
8537 	QTransform result;
8538 	if (isGroupChild())
8539 	{
8540 		QList<const PageItem*> itList;
8541 		const PageItem* ite = this;
8542 		while (ite->isGroupChild())
8543 		{
8544 			itList.prepend(ite);
8545 			ite = ite->Parent;
8546 		}
8547 		result.translate(ite->xPos(), ite->yPos());
8548 		result.rotate(ite->rotation());
8549 	/*	if (ite->isGroup() || ite->isSymbol())
8550 		{
8551 			if (ite->imageFlippedH())
8552 			{
8553 				result.translate(ite->width(), 0);
8554 				result.scale(-1, 1);
8555 			}
8556 			if (ite->imageFlippedV())
8557 			{
8558 				result.translate(0, ite->height());
8559 				result.scale(1, -1);
8560 			}
8561 		}*/
8562 		if (ite == this)
8563 			return result;
8564 		if (ite->isGroup())
8565 			result.scale(ite->width() / ite->groupWidth, ite->height() / ite->groupHeight);
8566 		for (int aa = 0; aa < itList.count(); aa++)
8567 		{
8568 			ite = itList.at(aa);
8569 			result.translate(ite->gXpos, ite->gYpos);
8570 			result.rotate(ite->rotation());
8571 		/*	if (ite->isGroup() || ite->isSymbol())
8572 			{
8573 				if (ite->imageFlippedH())
8574 				{
8575 					result.translate(ite->width(), 0);
8576 					result.scale(-1, 1);
8577 				}
8578 				if (ite->imageFlippedV())
8579 				{
8580 					result.translate(0, ite->height());
8581 					result.scale(1, -1);
8582 				}
8583 			}*/
8584 			if (ite == this)
8585 				return result;
8586 			if (ite->isGroup())
8587 				result.scale(ite->width() / ite->groupWidth, ite->height() / ite->groupHeight);
8588 		}
8589 	}
8590 	else
8591 	{
8592 		result.translate(m_xPos, m_yPos);
8593 		result.rotate(m_rotation);
8594 	}
8595 	return result;
8596 }
8597 
getTransform(double deltaX,double deltaY) const8598 QTransform PageItem::getTransform(double deltaX, double deltaY) const
8599 {
8600 	QTransform result;
8601 	if (isGroupChild())
8602 	{
8603 		QList<const PageItem*> itList;
8604 		const PageItem* ite = this;
8605 		while (ite->isGroupChild())
8606 		{
8607 			itList.prepend(ite);
8608 			ite = ite->Parent;
8609 		}
8610 		result.translate(ite->xPos(), ite->yPos());
8611 		result.rotate(ite->rotation());
8612 	/*	if (ite->isGroup() || ite->isSymbol())
8613 		{
8614 			if (ite->imageFlippedH())
8615 			{
8616 				result.translate(ite->width(), 0);
8617 				result.scale(-1, 1);
8618 			}
8619 			if (ite->imageFlippedV())
8620 			{
8621 				result.translate(0, ite->height());
8622 				result.scale(1, -1);
8623 			}
8624 		}*/
8625 		if (ite == this)
8626 			return result;
8627 		if (ite->isGroup())
8628 			result.scale(ite->width() / ite->groupWidth, ite->height() / ite->groupHeight);
8629 		for (int i = 0; i < itList.count(); i++)
8630 		{
8631 			ite = itList.at(i);
8632 			result.translate(ite->gXpos, ite->gYpos);
8633 			if (ite == this)
8634 				result.translate(deltaX, deltaY);
8635 			result.rotate(ite->rotation());
8636 		/*	if (ite->isGroup() || ite->isSymbol())
8637 			{
8638 				if (ite->imageFlippedH())
8639 				{
8640 					result.translate(ite->width(), 0);
8641 					result.scale(-1, 1);
8642 				}
8643 				if (ite->imageFlippedV())
8644 				{
8645 					result.translate(0, ite->height());
8646 					result.scale(1, -1);
8647 				}
8648 			}*/
8649 			if (ite == this)
8650 				return result;
8651 			if (ite->isGroup())
8652 				result.scale(ite->width() / ite->groupWidth, ite->height() / ite->groupHeight);
8653 		}
8654 	}
8655 	else
8656 	{
8657 		result.translate(m_xPos + deltaX, m_yPos + deltaY);
8658 		result.rotate(m_rotation);
8659 	}
8660 	return result;
8661 }
8662 
getBoundingRect() const8663 QRectF PageItem::getBoundingRect() const
8664 {
8665 	double x, y, x2, y2;
8666 	getBoundingRect(&x, &y, &x2, &y2);
8667 	return QRectF(x, y, x2 - x, y2 - y);
8668 }
8669 
getCurrentBoundingRect(double moreSpace) const8670 QRectF PageItem::getCurrentBoundingRect(double moreSpace) const
8671 {
8672 	double x = BoundingX - moreSpace / 2.0;
8673 	double y = BoundingY - moreSpace / 2.0;
8674 	double w = BoundingW + moreSpace;
8675 	double h = BoundingH + moreSpace;
8676 	QRectF ret = QRectF(x, y, w, h);
8677 	return ret;
8678 }
8679 
getOldBoundingRect() const8680 QRectF PageItem::getOldBoundingRect() const
8681 {
8682 	double x, y, x2, y2;
8683 	getOldBoundingRect(&x, &y, &x2, &y2);
8684 	return QRectF(x, y, x2 - x, y2 - y);
8685 }
8686 
getVisualBoundingRect() const8687 QRectF PageItem::getVisualBoundingRect() const
8688 {
8689 	double x, y, x2, y2;
8690 	getVisualBoundingRect(&x, &y, &x2, &y2);
8691 	return QRectF(x, y, x2 - x, y2 - y);
8692 }
8693 
getBoundingRect(double * x1,double * y1,double * x2,double * y2) const8694 void PageItem::getBoundingRect(double *x1, double *y1, double *x2, double *y2) const
8695 {
8696 	double minx =  std::numeric_limits<double>::max();
8697 	double miny =  std::numeric_limits<double>::max();
8698 	double maxx = -std::numeric_limits<double>::max();
8699 	double maxy = -std::numeric_limits<double>::max();
8700 	if (m_rotation != 0)
8701 	{
8702 		FPointArray pb;
8703 		pb.resize(0);
8704 		pb.addPoint(FPoint(m_xPos, m_yPos));
8705 		pb.addPoint(FPoint(m_width,    0.0, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
8706 		pb.addPoint(FPoint(m_width, m_height, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
8707 		pb.addPoint(FPoint(  0.0, m_height, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
8708 		for (uint pc = 0; pc < 4; ++pc)
8709 		{
8710 			minx = qMin(minx, pb.point(pc).x());
8711 			miny = qMin(miny, pb.point(pc).y());
8712 			maxx = qMax(maxx, pb.point(pc).x());
8713 			maxy = qMax(maxy, pb.point(pc).y());
8714 		}
8715 		*x1 = minx;
8716 		*y1 = miny;
8717 		*x2 = maxx;
8718 		*y2 = maxy;
8719 	}
8720 	else
8721 	{
8722 		*x1 = m_xPos;
8723 		*y1 = m_yPos;
8724 		*x2 = m_xPos + qMax(1.0, qMax(m_width, m_lineWidth));
8725 		*y2 = m_yPos + qMax(1.0, qMax(m_height, m_lineWidth));
8726 	}
8727 }
8728 
getOldBoundingRect(double * x1,double * y1,double * x2,double * y2) const8729 void PageItem::getOldBoundingRect(double *x1, double *y1, double *x2, double *y2) const
8730 {
8731 	double minx =  std::numeric_limits<double>::max();
8732 	double miny =  std::numeric_limits<double>::max();
8733 	double maxx = -std::numeric_limits<double>::max();
8734 	double maxy = -std::numeric_limits<double>::max();
8735 	if (oldRot != 0)
8736 	{
8737 		FPointArray pb;
8738 		pb.resize(0);
8739 		pb.addPoint(FPoint(oldXpos, oldYpos));
8740 		pb.addPoint(FPoint(oldWidth,    0.0, oldXpos, oldYpos, oldRot, 1.0, 1.0));
8741 		pb.addPoint(FPoint(oldWidth, oldHeight, oldXpos, oldYpos, oldRot, 1.0, 1.0));
8742 		pb.addPoint(FPoint(  0.0, oldHeight, oldXpos, oldYpos, oldRot, 1.0, 1.0));
8743 		for (uint pc = 0; pc < 4; ++pc)
8744 		{
8745 			minx = qMin(minx, pb.point(pc).x());
8746 			miny = qMin(miny, pb.point(pc).y());
8747 			maxx = qMax(maxx, pb.point(pc).x());
8748 			maxy = qMax(maxy, pb.point(pc).y());
8749 		}
8750 		*x1 = minx;
8751 		*y1 = miny;
8752 		*x2 = maxx;
8753 		*y2 = maxy;
8754 	}
8755 	else
8756 	{
8757 		*x1 = oldXpos;
8758 		*y1 = oldYpos;
8759 		*x2 = oldXpos + qMax(1.0, qMax(oldWidth, m_lineWidth));
8760 		*y2 = oldYpos + qMax(1.0, qMax(oldHeight, m_lineWidth));
8761 	}
8762 }
8763 
getVisualBoundingRect(double * x1,double * y1,double * x2,double * y2) const8764 void PageItem::getVisualBoundingRect(double * x1, double * y1, double * x2, double * y2) const
8765 {
8766 	double minx =  std::numeric_limits<double>::max();
8767 	double miny =  std::numeric_limits<double>::max();
8768 	double maxx = -std::numeric_limits<double>::max();
8769 	double maxy = -std::numeric_limits<double>::max();
8770 	double extraSpace = visualLineWidth() / 2.0;
8771 	if (m_rotation != 0)
8772 	{
8773 		FPointArray pb;
8774 		pb.resize(0);
8775 		pb.addPoint(FPoint(-extraSpace,					-extraSpace,				xPos(), yPos(), m_rotation, 1.0, 1.0));
8776 		pb.addPoint(FPoint(visualWidth()-extraSpace,	-extraSpace,				xPos(), yPos(), m_rotation, 1.0, 1.0));
8777 		pb.addPoint(FPoint(visualWidth()-extraSpace,	visualHeight()-extraSpace,	xPos(), yPos(), m_rotation, 1.0, 1.0));
8778 		pb.addPoint(FPoint(-extraSpace, 				visualHeight()-extraSpace,	xPos(), yPos(), m_rotation, 1.0, 1.0));
8779 		for (int pc = 0; pc < 4; ++pc)
8780 		{
8781 			minx = qMin(minx, pb.point(pc).x());
8782 			miny = qMin(miny, pb.point(pc).y());
8783 			maxx = qMax(maxx, pb.point(pc).x());
8784 			maxy = qMax(maxy, pb.point(pc).y());
8785 		}
8786 		*x1 = minx;
8787 		*y1 = miny;
8788 		*x2 = maxx;
8789 		*y2 = maxy;
8790 	}
8791 	else
8792 	{
8793 		*x1 = visualXPos();
8794 		*y1 = visualYPos();
8795 		*x2 = *x1 + qMax(visualWidth(), extraSpace);
8796 		*y2 = *y1 + qMax(visualHeight(), extraSpace);
8797 	}
8798 }
8799 
visualXPos() const8800 double PageItem::visualXPos() const
8801 {
8802 	double extraSpace = visualLineWidth() / 2.0;
8803 	return m_xPos - extraSpace;
8804 }
8805 
visualYPos() const8806 double PageItem::visualYPos() const
8807 {
8808 	double extraSpace = visualLineWidth() / 2.0;
8809 	return m_yPos - extraSpace;
8810 }
8811 
visualWidth() const8812 double PageItem::visualWidth() const
8813 {
8814 	double extraSpace = visualLineWidth();
8815 	return m_width + extraSpace;
8816 }
8817 
visualHeight() const8818 double PageItem::visualHeight() const
8819 {
8820 	double extraSpace = visualLineWidth();
8821 	return m_height + extraSpace;
8822 }
8823 
visualLineWidth() const8824 double PageItem::visualLineWidth() const
8825 {
8826 	double extraSpace = 0.0;
8827 	if (NamedLStyle.isEmpty())
8828 	{
8829 		if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0))
8830 		{
8831 			extraSpace = m_lineWidth;
8832 			if ((extraSpace == 0.0) && m_Doc->view()) // Hairline case
8833 				extraSpace = 1.0 / m_Doc->view()->scale();
8834 		}
8835 		if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal)) && (patternStrokePath))
8836 		{
8837 			ScPattern *pat = &m_Doc->docPatterns[patternStrokeVal];
8838 			QTransform mat;
8839 			mat.rotate(patternStrokeRotation);
8840 			mat.scale(patternStrokeScaleX / 100.0, patternStrokeScaleY / 100.0);
8841 			QRectF p1R = QRectF(0, 0, pat->width, pat->height);
8842 			QRectF p2R = mat.map(p1R).boundingRect();
8843 			extraSpace = p2R.height();
8844 		}
8845 	}
8846 	else
8847 	{
8848 		multiLine ml = m_Doc->docLineStyles[NamedLStyle];
8849 		const SingleLine& sl = ml.last();
8850 		if (sl.Color != CommonStrings::None)
8851 		{
8852 			extraSpace = sl.Width;
8853 			if ((extraSpace == 0.0) && m_Doc->view()) // Hairline case
8854 				extraSpace = 1.0 / m_Doc->view()->scale();
8855 		}
8856 	}
8857 	return extraSpace;
8858 }
8859 
getStartArrowBoundingRect() const8860 QRectF PageItem::getStartArrowBoundingRect() const
8861 {
8862 	QRectF arrowRect;
8863 	if (m_startArrowIndex != 0 && !PoLine.empty())
8864 	{
8865 		QTransform arrowTrans;
8866 		FPointArray arrow = m_Doc->arrowStyles().at(m_startArrowIndex - 1).points.copy();
8867 		arrowTrans.translate(m_xPos, m_yPos);
8868 		arrowTrans.rotate(m_rotation);
8869 		const FPoint& Start = PoLine.point(0);
8870 		for (int xx = 1; xx < PoLine.size(); xx += 2)
8871 		{
8872 			const FPoint& Vector = PoLine.point(xx);
8873 			if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
8874 			{
8875 				arrowTrans.translate(Start.x(), Start.y());
8876 				arrowTrans.rotate(atan2(Start.y() - Vector.y(), Start.x() - Vector.x()) * (180.0 / M_PI));
8877 				arrowTrans.scale(m_startArrowScale / 100.0, m_startArrowScale / 100.0);
8878 				if (NamedLStyle.isEmpty())
8879 				{
8880 					if (m_lineWidth != 0.0)
8881 						arrowTrans.scale(m_lineWidth, m_lineWidth);
8882 				}
8883 				else
8884 				{
8885 					const multiLine ml = m_Doc->docLineStyles[NamedLStyle];
8886 					const SingleLine& sl = ml.last();
8887 					if (sl.Width != 0.0)
8888 						arrowTrans.scale(sl.Width, sl.Width);
8889 				}
8890 				arrow.map(arrowTrans);
8891 				break;
8892 			}
8893 		}
8894 		FPoint minAr = getMinClipF(&arrow);
8895 		FPoint maxAr = getMaxClipF(&arrow);
8896 		arrowRect = QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()));
8897 	}
8898 
8899 	return arrowRect;
8900 }
8901 
getStartArrowOldBoundingRect() const8902 QRectF PageItem::getStartArrowOldBoundingRect() const
8903 {
8904 	QRectF arrowRect;
8905 	if (m_startArrowIndex != 0 && !PoLine.empty())
8906 	{
8907 		QTransform arrowTrans;
8908 		FPointArray arrow = m_Doc->arrowStyles().at(m_startArrowIndex - 1).points.copy();
8909 		arrowTrans.translate(oldXpos, oldYpos);
8910 		arrowTrans.rotate(oldRot);
8911 		FPoint Start = PoLine.point(0);
8912 		for (int xx = 1; xx < PoLine.size(); xx += 2)
8913 		{
8914 			FPoint Vector = PoLine.point(xx);
8915 			if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
8916 			{
8917 				arrowTrans.translate(Start.x(), Start.y());
8918 				arrowTrans.rotate(atan2(Start.y() - Vector.y(), Start.x() - Vector.x()) * (180.0 / M_PI));
8919 				arrowTrans.scale(m_startArrowScale / 100.0, m_startArrowScale / 100.0);
8920 				if (NamedLStyle.isEmpty())
8921 				{
8922 					if (m_oldLineWidth != 0.0)
8923 						arrowTrans.scale(m_oldLineWidth, m_oldLineWidth);
8924 				}
8925 				else
8926 				{
8927 					const multiLine ml = m_Doc->docLineStyles[NamedLStyle];
8928 					const SingleLine& sl = ml.last();
8929 					if (sl.Width != 0.0)
8930 						arrowTrans.scale(sl.Width, sl.Width);
8931 				}
8932 				arrow.map(arrowTrans);
8933 				break;
8934 			}
8935 		}
8936 		FPoint minAr = getMinClipF(&arrow);
8937 		FPoint maxAr = getMaxClipF(&arrow);
8938 		arrowRect = QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()));
8939 	}
8940 
8941 	return arrowRect;
8942 }
8943 
getEndArrowBoundingRect() const8944 QRectF PageItem::getEndArrowBoundingRect() const
8945 {
8946 	QRectF arrowRect;
8947 	if (m_endArrowIndex != 0 && PoLine.size() >= 2)
8948 	{
8949 		QTransform arrowTrans;
8950 		FPointArray arrow = m_Doc->arrowStyles().at(m_endArrowIndex - 1).points.copy();
8951 		arrowTrans.translate(m_xPos, m_yPos);
8952 		arrowTrans.rotate(m_rotation);
8953 		FPoint End = PoLine.point(PoLine.size() - 2);
8954 		for (uint xx = PoLine.size() - 1; xx > 0; xx -= 2)
8955 		{
8956 			FPoint Vector = PoLine.point(xx);
8957 			if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
8958 			{
8959 				arrowTrans.translate(End.x(), End.y());
8960 				arrowTrans.rotate(atan2(End.y() - Vector.y(), End.x() - Vector.x()) * (180.0 / M_PI));
8961 				arrowTrans.scale(m_endArrowScale / 100.0, m_endArrowScale / 100.0);
8962 				if (NamedLStyle.isEmpty())
8963 				{
8964 					if (m_lineWidth != 0.0)
8965 						arrowTrans.scale(m_lineWidth, m_lineWidth);
8966 				}
8967 				else
8968 				{
8969 					const multiLine ml = m_Doc->docLineStyles[NamedLStyle];
8970 					const SingleLine& sl = ml.last();
8971 					if (sl.Width != 0.0)
8972 						arrowTrans.scale(sl.Width, sl.Width);
8973 				}
8974 				arrow.map(arrowTrans);
8975 				break;
8976 			}
8977 		}
8978 		FPoint minAr = getMinClipF(&arrow);
8979 		FPoint maxAr = getMaxClipF(&arrow);
8980 		arrowRect = QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()));
8981 	}
8982 
8983 	return arrowRect;
8984 }
8985 
getEndArrowOldBoundingRect() const8986 QRectF PageItem::getEndArrowOldBoundingRect() const
8987 {
8988 	QRectF arrowRect;
8989 	if (m_endArrowIndex != 0 && PoLine.size() >= 2)
8990 	{
8991 		QTransform arrowTrans;
8992 		FPointArray arrow = m_Doc->arrowStyles().at(m_endArrowIndex - 1).points.copy();
8993 		arrowTrans.translate(oldXpos, oldYpos);
8994 		arrowTrans.rotate(oldRot);
8995 		FPoint End = PoLine.point(PoLine.size() - 2);
8996 		for (uint xx = PoLine.size()-1; xx > 0; xx -= 2)
8997 		{
8998 			FPoint Vector = PoLine.point(xx);
8999 			if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
9000 			{
9001 				arrowTrans.translate(End.x(), End.y());
9002 				arrowTrans.rotate(atan2(End.y() - Vector.y(), End.x() - Vector.x()) * (180.0 / M_PI));
9003 				arrowTrans.scale(m_endArrowScale / 100.0, m_endArrowScale / 100.0);
9004 				if (NamedLStyle.isEmpty())
9005 				{
9006 					if (m_oldLineWidth != 0.0)
9007 						arrowTrans.scale(m_oldLineWidth, m_oldLineWidth);
9008 				}
9009 				else
9010 				{
9011 					const multiLine ml = m_Doc->docLineStyles[NamedLStyle];
9012 					const SingleLine& sl = ml.last();
9013 					if (sl.Width != 0.0)
9014 						arrowTrans.scale(sl.Width, sl.Width);
9015 				}
9016 				arrow.map(arrowTrans);
9017 				break;
9018 			}
9019 		}
9020 		FPoint minAr = getMinClipF(&arrow);
9021 		FPoint maxAr = getMaxClipF(&arrow);
9022 		arrowRect = QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()));
9023 	}
9024 
9025 	return arrowRect;
9026 }
9027 
textInteractionRegion(double xOffset,double yOffset) const9028 QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
9029 {
9030 	QRegion res;
9031 	if (m_textFlowMode == TextFlowDisabled)
9032 		return res;
9033 
9034 	QTransform pp;
9035 	if (this->isGroupChild())
9036 		pp.translate(gXpos, gYpos);
9037 	else
9038 		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
9039 	pp.rotate(m_rotation);
9040 
9041 	if (textFlowUsesBoundingBox())
9042 	{
9043 		QRectF bb = getVisualBoundingRect();
9044 		if (isGroupChild())
9045 		{
9046 			bb.translate(-m_xPos, -m_yPos);
9047 			bb.translate(gXpos, gYpos);
9048 		}
9049 		res = QRegion(bb.toRect());
9050 	}
9051 	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
9052 	{
9053 		QList<uint> Segs;
9054 		QPolygon Clip2 = flattenPath(imageClip, Segs);
9055 		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
9056 	}
9057 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
9058 	{
9059 		QList<uint> Segs;
9060 		QPolygon Clip2 = flattenPath(ContourLine, Segs);
9061 		res = QRegion(pp.map(Clip2));
9062 	}
9063 	else
9064 	{
9065 		if (isSymbol() || isGroup())
9066 		{
9067 			if (imageFlippedH())
9068 			{
9069 				pp.translate(m_width, 0);
9070 				pp.scale(-1, 1);
9071 			}
9072 			if (imageFlippedV())
9073 			{
9074 				pp.translate(0, m_height);
9075 				pp.scale(1, -1);
9076 			}
9077 		}
9078 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
9079 		{
9080 //			QVector<double> m_array;
9081 			QPainterPath ppa;
9082 			QPainterPath result;
9083 			if (itemType() == PageItem::PolyLine)
9084 				ppa = PoLine.toQPainterPath(false);
9085 			else
9086 				ppa = PoLine.toQPainterPath(true);
9087 			if (NamedLStyle.isEmpty())
9088 			{
9089 				QPainterPathStroker stroke;
9090 				stroke.setCapStyle(PLineEnd);
9091 				stroke.setJoinStyle(PLineJoin);
9092 				stroke.setDashPattern(Qt::SolidLine);
9093 				stroke.setWidth(m_lineWidth);
9094 				result = stroke.createStroke(ppa);
9095 			}
9096 			else
9097 			{
9098 				multiLine ml = doc()->docLineStyles[NamedLStyle];
9099 				int ind = ml.size()-1;
9100 				if ((ml[ind].Color != CommonStrings::None) && (ml[ind].Width != 0))
9101 				{
9102 					QPainterPathStroker stroke;
9103 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
9104 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
9105 					stroke.setDashPattern(Qt::SolidLine);
9106 					stroke.setWidth(ml[ind].Width);
9107 					result = stroke.createStroke(ppa);
9108 				}
9109 			}
9110 			res = QRegion(pp.map(Clip));
9111 			QList<QPolygonF> pl = result.toSubpathPolygons();
9112 			for (int b = 0; b < pl.count(); b++)
9113 			{
9114 				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
9115 			}
9116 		}
9117 		else
9118 			res = QRegion(pp.map(Clip));
9119 	}
9120 	return  res;
9121 }
9122 
pointWithinItem(int x,const int y) const9123 bool PageItem::pointWithinItem(int x, const int y) const
9124 {
9125 	const_cast<PageItem*>(this)-> setRedrawBounding();
9126 	// FIXME: We should be rounding or truncating here, not letting the compiler do it.
9127 	// Should we be rounding, truncating up, or truncating down?
9128 	//CB is this now correct?
9129 	QRect itemRect( static_cast<int>(floor(BoundingX)), static_cast<int>(floor(BoundingY)), static_cast<int>(ceil(BoundingW)), static_cast<int>(ceil(BoundingH)) );
9130 	return itemRect.contains(x, y);
9131 }
9132 
mouseWithinItem(int x,int y,double scale) const9133 bool PageItem::mouseWithinItem(int x, int y, double scale) const
9134 {
9135 	QTransform p;
9136 	p.translate(m_xPos*scale, m_yPos*scale);
9137 	p.scale(scale, scale);
9138 	p.rotate(rotation());
9139 	QRectF transRect(p.mapRect(QRectF(0.0, 0.0, width(), height())));
9140 	return transRect.contains(x, y);
9141 }
9142 
getImageEffectsModifier() const9143 QString PageItem::getImageEffectsModifier() const
9144 {
9145 	bool first = true;
9146 	QString buffer;
9147 	QTextStream ts(&buffer);
9148 	ScImageEffectList::const_iterator i = effectsInUse.begin();
9149 	while (i != effectsInUse.end())
9150 	{
9151 		if (first)
9152 			first = false;
9153 		else
9154 			ts << "/";
9155 		ts << i->effectCode << ":" << i->effectParameters;
9156 		i++;
9157 	}
9158 	return buffer;
9159 }
9160 
loadImage(const QString & filename,const bool reload,const int gsResolution,bool showMsg)9161 bool PageItem::loadImage(const QString& filename, const bool reload, const int gsResolution, bool showMsg)
9162 {
9163 	bool useImage = (asImageFrame() != nullptr);
9164 	useImage |= (isAnnotation() && annotation().UseIcons());
9165 	if (!useImage)
9166 		return false;
9167 	QFileInfo fi(filename);
9168 	QString clPath(pixm.imgInfo.usedPath);
9169 	pixm.imgInfo.valid = false;
9170 	pixm.imgInfo.clipPath.clear();
9171 	pixm.imgInfo.PDSpathData.clear();
9172 	pixm.imgInfo.layerInfo.clear();
9173 	pixm.imgInfo.usedPath.clear();
9174 	imageClip.resize(0);
9175 	int lowResTypeBack = pixm.imgInfo.lowResType;
9176 	int gsRes = gsResolution;
9177 	if (gsResolution == -1) //If it wasn't supplied, get it from PrefsManager.
9178 		gsRes = PrefsManager::instance().gsResolution();
9179 	bool dummy;
9180 
9181 	CMSettings cms(m_Doc, ImageProfile, ImageIntent);
9182 	cms.setUseEmbeddedProfile(UseEmbedded);
9183 	cms.allowSoftProofing(true);
9184 
9185 	ScImageCacheProxy imgcache(filename);
9186 	imgcache.addModifier("lowResType", QString::number(pixm.imgInfo.lowResType));
9187 	if (!effectsInUse.isEmpty())
9188 		imgcache.addModifier("effectsInUse", getImageEffectsModifier());
9189 
9190 	bool fromCache = false;
9191 	if (!pixm.loadPicture(imgcache, fromCache, pixm.imgInfo.actualPageNumber, cms, ScImage::RGBData, gsRes, &dummy, showMsg))
9192 	{
9193 		Pfile = fi.absoluteFilePath();
9194 		imageIsAvailable = false;
9195 		return false;
9196 	}
9197 
9198 	QString ext = fi.suffix().toLower();
9199 	if (UndoManager::undoEnabled() && !reload)
9200 	{
9201 		ScItemState<ScImageEffectList> *is = new ScItemState<ScImageEffectList>(Um::GetImage, filename, Um::IGetImage);
9202 		is->set("GET_IMAGE");
9203 		is->set("OLD_IMAGE_PATH", Pfile);
9204 		is->set("NEW_IMAGE_PATH", filename);
9205 		is->set("FLIPPH",imageFlippedH());
9206 		is->set("FLIPPV",imageFlippedV());
9207 		is->set("SCALING",ScaleType);
9208 		is->set("ASPECT",AspectRatio);
9209 		is->set("XOFF",imageXOffset());
9210 		is->set("XSCALE",imageXScale());
9211 		is->set("YOFF",imageYOffset());
9212 		is->set("YSCALE",imageYScale());
9213 		is->set("FILLT", fillTransparency());
9214 		is->set("LINET", lineTransparency());
9215 		is->setItem(effectsInUse);
9216 		undoManager->action(this, is);
9217 	}
9218 	double xres = pixm.imgInfo.xres;
9219 	double yres = pixm.imgInfo.yres;
9220 	imageIsAvailable = true;
9221 
9222 	if (Pfile != filename)
9223 	{
9224 		oldLocalScX = m_imageXScale = 72.0 / xres;
9225 		oldLocalScY = m_imageYScale = 72.0 / yres;
9226 		oldLocalX = m_imageXOffset = 0;
9227 		oldLocalY = m_imageYOffset = 0;
9228 		if ((m_Doc->itemToolPrefs().imageUseEmbeddedPath) && (!pixm.imgInfo.clipPath.isEmpty()))
9229 		{
9230 			pixm.imgInfo.usedPath = pixm.imgInfo.clipPath;
9231 			clPath = pixm.imgInfo.clipPath;
9232 			if (pixm.imgInfo.PDSpathData.contains(clPath))
9233 			{
9234 				imageClip = pixm.imgInfo.PDSpathData[clPath].copy();
9235 				pixm.imgInfo.usedPath = clPath;
9236 				QTransform cl;
9237 				cl.translate(m_imageXOffset*m_imageXScale, m_imageYOffset*m_imageYScale);
9238 				cl.scale(m_imageXScale, m_imageYScale);
9239 				imageClip.map(cl);
9240 			}
9241 		}
9242 	}
9243 
9244 	Pfile = fi.absoluteFilePath();
9245 	if (reload && pixm.imgInfo.PDSpathData.contains(clPath))
9246 	{
9247 		imageClip = pixm.imgInfo.PDSpathData[clPath].copy();
9248 		pixm.imgInfo.usedPath = clPath;
9249 		QTransform cl;
9250 		cl.translate(m_imageXOffset*m_imageXScale, m_imageYOffset*m_imageYScale);
9251 		cl.scale(m_imageXScale, m_imageYScale);
9252 		imageClip.map(cl);
9253 	}
9254 	BBoxX = pixm.imgInfo.BBoxX;
9255 	BBoxH = pixm.imgInfo.BBoxH;
9256 	if (fromCache)
9257 	{
9258 		OrigW = imgcache.getInfo("OrigW").toInt();
9259 		OrigH = imgcache.getInfo("OrigH").toInt();
9260 	}
9261 	else
9262 	{
9263 		OrigW = pixm.width();
9264 		OrigH = pixm.height();
9265 		imgcache.addInfo("OrigW", QString::number(OrigW));
9266 		imgcache.addInfo("OrigH", QString::number(OrigH));
9267 	}
9268 
9269 	isRaster = !(extensionIndicatesPDF(ext) || extensionIndicatesEPSorPS(ext));
9270 	if (!isRaster)
9271 	{
9272 		effectsInUse.clear();
9273 		imgcache.delModifier("effectsInUse");
9274 	}
9275 
9276 	UseEmbedded = pixm.imgInfo.isEmbedded;
9277 	if (pixm.imgInfo.isEmbedded)
9278 		ImageProfile = "Embedded " + pixm.imgInfo.profileName;
9279 	else
9280 		ImageProfile = pixm.imgInfo.profileName;
9281 	if (!pixm.imgInfo.embeddedProfileName.isEmpty())
9282 		EmbeddedProfile = "Embedded " + pixm.imgInfo.embeddedProfileName;
9283 	else
9284 		EmbeddedProfile.clear();
9285 
9286 	adjustPictScale();
9287 
9288 	// #12408 : we set the old* variables to avoid creation of unwanted undo states
9289 	// when user perform actions such as double clicking image. We might want to
9290 	// create an undo transaction in this function if this does not work properly.
9291 	oldLocalScX = m_imageXScale;
9292 	oldLocalScY = m_imageYScale;
9293 
9294 	if (imageIsAvailable && !fromCache)
9295 	{
9296 		if ((pixm.imgInfo.colorspace == ColorSpaceDuotone) && (pixm.imgInfo.duotoneColors.count() != 0) && (!reload))
9297 		{
9298 			QString efVal = "";
9299 			for (int cc = 0; cc < pixm.imgInfo.duotoneColors.count(); cc++)
9300 			{
9301 				if (!m_Doc->PageColors.contains(pixm.imgInfo.duotoneColors[cc].Name))
9302 					m_Doc->PageColors.insert(pixm.imgInfo.duotoneColors[cc].Name, pixm.imgInfo.duotoneColors[cc].Color);
9303 				efVal += pixm.imgInfo.duotoneColors[cc].Name + "\n";
9304 			}
9305 			m_Doc->scMW()->propertiesPalette->updateColorList();
9306 			m_Doc->scMW()->contentPalette->updateColorList();
9307 			struct ImageEffect ef;
9308 			if (pixm.imgInfo.duotoneColors.count() == 1)
9309 			{
9310 				efVal += "100";
9311 				ef.effectCode = ImageEffect::EF_COLORIZE;
9312 				ef.effectParameters = efVal;
9313 			}
9314 			else if (pixm.imgInfo.duotoneColors.count() == 2)
9315 			{
9316 				efVal += "100 100";
9317 				QString tmp;
9318 				FPointArray Vals = pixm.imgInfo.duotoneColors[0].Curve;
9319 				tmp.setNum(Vals.size());
9320 				efVal += " "+tmp;
9321 				for (int p = 0; p < Vals.size(); p++)
9322 				{
9323 					const FPoint& pv = Vals.point(p);
9324 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9325 				}
9326 				efVal += " 0";
9327 				Vals = pixm.imgInfo.duotoneColors[1].Curve;
9328 				tmp.setNum(Vals.size());
9329 				efVal += " "+tmp;
9330 				for (int p = 0; p < Vals.size(); p++)
9331 				{
9332 					const FPoint& pv = Vals.point(p);
9333 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9334 				}
9335 				efVal += " 0";
9336 				ef.effectCode = ImageEffect::EF_DUOTONE;
9337 				ef.effectParameters = efVal;
9338 			}
9339 			else if (pixm.imgInfo.duotoneColors.count() == 3)
9340 			{
9341 				efVal += "100 100 100";
9342 				QString tmp;
9343 				FPointArray Vals = pixm.imgInfo.duotoneColors[0].Curve;
9344 				tmp.setNum(Vals.size());
9345 				efVal += " "+tmp;
9346 				for (int p = 0; p < Vals.size(); p++)
9347 				{
9348 					const FPoint& pv = Vals.point(p);
9349 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9350 				}
9351 				efVal += " 0";
9352 				Vals = pixm.imgInfo.duotoneColors[1].Curve;
9353 				tmp.setNum(Vals.size());
9354 				efVal += " "+tmp;
9355 				for (int p = 0; p < Vals.size(); p++)
9356 				{
9357 					const FPoint& pv = Vals.point(p);
9358 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9359 				}
9360 				efVal += " 0";
9361 				Vals = pixm.imgInfo.duotoneColors[2].Curve;
9362 				tmp.setNum(Vals.size());
9363 				efVal += " "+tmp;
9364 				for (int p = 0; p < Vals.size(); p++)
9365 				{
9366 					const FPoint& pv = Vals.point(p);
9367 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9368 				}
9369 				efVal += " 0";
9370 				ef.effectCode = ImageEffect::EF_TRITONE;
9371 				ef.effectParameters = efVal;
9372 			}
9373 			else if (pixm.imgInfo.duotoneColors.count() == 4)
9374 			{
9375 				efVal += "100 100 100 100";
9376 				QString tmp;
9377 				FPointArray Vals = pixm.imgInfo.duotoneColors[0].Curve;
9378 				tmp.setNum(Vals.size());
9379 				efVal += " "+tmp;
9380 				for (int p = 0; p < Vals.size(); p++)
9381 				{
9382 					const FPoint& pv = Vals.point(p);
9383 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9384 				}
9385 				efVal += " 0";
9386 				Vals = pixm.imgInfo.duotoneColors[1].Curve;
9387 				tmp.setNum(Vals.size());
9388 				efVal += " "+tmp;
9389 				for (int p = 0; p < Vals.size(); p++)
9390 				{
9391 					const FPoint& pv = Vals.point(p);
9392 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9393 				}
9394 				efVal += " 0";
9395 				Vals = pixm.imgInfo.duotoneColors[2].Curve;
9396 				tmp.setNum(Vals.size());
9397 				efVal += " "+tmp;
9398 				for (int p = 0; p < Vals.size(); p++)
9399 				{
9400 					const FPoint& pv = Vals.point(p);
9401 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9402 				}
9403 				efVal += " 0";
9404 				Vals = pixm.imgInfo.duotoneColors[3].Curve;
9405 				tmp.setNum(Vals.size());
9406 				efVal += " "+tmp;
9407 				for (int p = 0; p < Vals.size(); p++)
9408 				{
9409 					const FPoint& pv = Vals.point(p);
9410 					efVal += QString(" %1 %2").arg(pv.x()).arg(pv.y());
9411 				}
9412 				efVal += " 0";
9413 				ef.effectCode = ImageEffect::EF_QUADTONE;
9414 				ef.effectParameters = efVal;
9415 			}
9416 			effectsInUse.append(ef);
9417 			imgcache.addModifier("effectsInUse", getImageEffectsModifier());
9418 		}
9419 		pixm.applyEffect(effectsInUse, m_Doc->PageColors, false);
9420 //		if (reload)
9421 			pixm.imgInfo.lowResType = lowResTypeBack;
9422 		if (pixm.imgInfo.lowResType != 0)
9423 		{
9424 			double scaling = pixm.imgInfo.xres / 36.0;
9425 			if (pixm.imgInfo.lowResType == 1)
9426 				scaling = pixm.imgInfo.xres / 72.0;
9427 			// Prevent exagerately large images when using low res preview modes
9428 			uint pixels = qRound(pixm.width() * pixm.height() / (scaling * scaling));
9429 			if (pixels > 3000000)
9430 			{
9431 				double ratio = pixels / 3000000.0;
9432 				scaling *= sqrt(ratio);
9433 			}
9434 			if (pixm.createLowRes(scaling))
9435 			{
9436 				pixm.imgInfo.lowResScale = scaling;
9437 				pixm.saveCache(imgcache);
9438 			}
9439 			else
9440 				pixm.imgInfo.lowResScale = 1.0;
9441 		}
9442 	}
9443 	if (imageIsAvailable && m_Doc->viewAsPreview)
9444 	{
9445 		VisionDefectColor defect;
9446 		QColor tmpC;
9447 		int h = pixm.qImagePtr()->height();
9448 		int w = pixm.qImagePtr()->width();
9449 		int r, g, b, a;
9450 		QRgb *s;
9451 		QRgb rgb;
9452 		for (int yi=0; yi < h; ++yi)
9453 		{
9454 			s = (QRgb*)(pixm.qImagePtr()->scanLine( yi ));
9455 			for (int xi = 0; xi < w; ++xi)
9456 			{
9457 				rgb = *s;
9458 				tmpC.setRgb(rgb);
9459 				tmpC = defect.convertDefect(tmpC, m_Doc->previewVisual);
9460 				a = qAlpha(rgb);
9461 				tmpC.getRgb(&r, &g, &b);
9462 				*s = qRgba(r, g, b, a);
9463 				s++;
9464 			}
9465 		}
9466 	}
9467 	return true;
9468 }
9469 
9470 
drawLockedMarker(ScPainter * p)9471 void PageItem::drawLockedMarker(ScPainter *p)
9472 {
9473 	//TODO: CB clean
9474 	double scp1 = p->zoomFactor() ;
9475 	double ofwh = 6 * scp1;
9476 	double ofx = m_width - ofwh/2;
9477 	double ofy = m_height - ofwh*1.5;
9478 	double bx1= ofx+ scp1;
9479 	double by1= ofy+3 * scp1;
9480 	double bw= 4*scp1;
9481 	double bh= 2*scp1;
9482 	p->setPen(Qt::black, 0.5 / p->zoomFactor(), Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
9483 	p->setPenOpacity(1.0);
9484 	p->setBrush(Qt::white);
9485 	p->setBrushOpacity(1.0);
9486 	p->setFillMode(ScPainter::Solid);
9487 	p->drawRect(ofx, ofy, ofwh, ofwh);
9488 	p->setBrush(Qt::black);
9489 	p->drawRect(bx1, by1, bw, bh);
9490 	p->setPen(Qt::black, 1.5 / p->zoomFactor(), Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
9491 	if (m_Locked)
9492 		p->drawLine(FPoint(bx1+scp1/2, ofy+scp1), FPoint(bx1+scp1/2, by1));
9493 	p->drawLine(FPoint(bx1+scp1*3.5, ofy+scp1), FPoint(bx1+scp1*3.5, by1));
9494 	p->drawLine(FPoint(bx1+scp1/2, ofy+scp1), FPoint(bx1+scp1*3.5, ofy+scp1));
9495 }
9496 
drawArrow(ScPainter * p,QTransform & arrowTrans,int arrowIndex)9497 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
9498 {
9499 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex-1).points.copy();
9500 	if (NamedLStyle.isEmpty())
9501 	{
9502 		if (m_lineWidth != 0.0)
9503 			arrowTrans.scale(m_lineWidth, m_lineWidth);
9504 	}
9505 	else
9506 	{
9507 		multiLine ml = m_Doc->docLineStyles[NamedLStyle];
9508 		if (ml[ml.size()-1].Width != 0.0)
9509 			arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
9510 	}
9511 	arrow.map(arrowTrans);
9512 	p->setupPolygon(&arrow);
9513 	if (m_Doc->layerOutline(m_layerID))
9514 		p->strokePath();
9515 	else
9516 	{
9517 		if (NamedLStyle.isEmpty())
9518 		{
9519 			ScPattern *strokePattern = m_Doc->checkedPattern(patternStrokeVal);
9520 			if (strokePattern)
9521 			{
9522 				p->setPattern(strokePattern, patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY);
9523 				p->setFillMode(ScPainter::Pattern);
9524 				p->fillPath();
9525 			}
9526 			else if (GrTypeStroke > 0)
9527 			{
9528 				if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal)))
9529 					gradientStrokeVal.clear();
9530 				if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal)))
9531 					stroke_gradient = m_Doc->docGradients[gradientStrokeVal];
9532 				if (stroke_gradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
9533 				{
9534 					if (lineColor() != CommonStrings::None)
9535 					{
9536 						p->setBrush(m_strokeQColor);
9537 						p->setBrushOpacity(1.0 - lineTransparency());
9538 						p->setLineWidth(0);
9539 						p->setFillMode(ScPainter::Solid);
9540 					}
9541 					else
9542 						p->setFillMode(ScPainter::None);
9543 				}
9544 				else
9545 				{
9546 					p->setFillMode(ScPainter::Gradient);
9547 					p->fill_gradient = stroke_gradient;
9548 					if (GrTypeStroke == Gradient_Linear)
9549 						p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew);
9550 					else
9551 						p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew);
9552 				}
9553 				p->fillPath();
9554 			}
9555 			else if (lineColor() != CommonStrings::None)
9556 			{
9557 				p->setBrush(m_strokeQColor);
9558 				p->setBrushOpacity(1.0 - lineTransparency());
9559 				p->setLineWidth(0);
9560 				p->setFillMode(ScPainter::Solid);
9561 				p->fillPath();
9562 			}
9563 		}
9564 		else
9565 		{
9566 			multiLine ml = m_Doc->docLineStyles[NamedLStyle];
9567 			QColor tmp;
9568 			if (ml[0].Color != CommonStrings::None)
9569 			{
9570 				SetQColor(&tmp, ml[0].Color, ml[0].Shade);
9571 				p->setBrush(tmp);
9572 				p->setLineWidth(0);
9573 				p->setFillMode(ScPainter::Solid);
9574 				p->fillPath();
9575 			}
9576 			for (int it = ml.size()-1; it > 0; it--)
9577 			{
9578 				if (ml[it].Color != CommonStrings::None)
9579 				{
9580 					SetQColor(&tmp, ml[it].Color, ml[it].Shade);
9581 					p->setPen(tmp, ml[it].Width, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
9582 					p->strokePath();
9583 				}
9584 			}
9585 		}
9586 	}
9587 }
9588 
adjustPictScale()9589 void PageItem::adjustPictScale()
9590 {
9591 	if (itemType() != PageItem::ImageFrame)
9592 		return;
9593 	if (ScaleType)
9594 		return;
9595 	if (OrigW == 0 || OrigH == 0)
9596 		return;
9597 	double xs = m_width / static_cast<double>(OrigW);
9598 	double ys = m_height / static_cast<double>(OrigH);
9599 	double imgXOffs = m_imageXOffset;
9600 	double imgYOffs = m_imageYOffset;
9601 	double imageRot = fmod(m_imageRotation, 360);
9602 	if (imageRot != 0.0)
9603 	{
9604 		QRectF br = QRectF(0, 0, OrigW, OrigH);
9605 		QTransform m;
9606 		m.rotate(m_imageRotation);
9607 		br = m.mapRect(br);
9608 		xs = m_width / br.width();
9609 		ys = m_height / br.height();
9610 		double xs2 = AspectRatio ? qMin(xs, ys) : xs;
9611 		double ys2 = AspectRatio ? qMin(xs, ys) : ys;
9612 		QLineF wL = QLineF(0, 0, OrigW, 0);
9613 		QLineF hL = QLineF(0, 0, 0, OrigH);
9614 		QTransform mm;
9615 		mm.scale(xs2, ys2);
9616 		mm.rotate(-m_imageRotation);
9617 		hL = mm.map(hL);
9618 		wL = mm.map(wL);
9619 		xs = wL.length() / static_cast<double>(OrigW);
9620 		ys = hL.length() / static_cast<double>(OrigH);
9621 	}
9622 	if (AspectRatio)
9623 	{
9624 		m_imageXScale = qMin(xs, ys);
9625 		m_imageYScale = qMin(xs, ys);
9626 	}
9627 	else
9628 	{
9629 		m_imageXScale = xs;
9630 		m_imageYScale = ys;
9631 	}
9632 	if (imageRot != 0.0)
9633 	{
9634 		QRectF br = QRectF(0, 0, OrigW * xs, OrigH * ys);
9635 		QTransform m;
9636 		m.scale(1.0 / xs, 1.0 / ys);
9637 		m.rotate(m_imageRotation);
9638 		br = m.mapRect(br);
9639 		m_imageXOffset = -br.x();
9640 		m_imageYOffset = -br.y();
9641 	}
9642 	else
9643 	{
9644 		m_imageXOffset = 0.0;
9645 		m_imageYOffset = 0.0;
9646 	}
9647 	// Disable broken code. Code must be independent from doc in that function
9648 	/*switch (m_Doc->RotMode)
9649 	{
9650 		case 0:
9651 			LocalX = 0;
9652 			LocalY = 0;
9653 			break;
9654 		case 1:
9655 			LocalX = (Width - static_cast<double>(OrigW) * LocalScX) / LocalScX;
9656 			LocalY = 0;
9657 			break;
9658 		case 2:
9659 			LocalX = ((Width - static_cast<double>(OrigW) * LocalScX) / LocalScX) / 2.0;
9660 			LocalY = ((Height - static_cast<double>(OrigH) * LocalScY) / LocalScY) / 2.0;
9661 			break;
9662 		case 3:
9663 			LocalX = 0;
9664 			LocalY = (Height - static_cast<double>(OrigH) * LocalScY) / LocalScY;
9665 			break;
9666 		case 4:
9667 			LocalX = (Width - static_cast<double>(OrigW) * LocalScX) / LocalScX;
9668 			LocalY = (Height - static_cast<double>(OrigH) * LocalScY) / LocalScY;
9669 			break;
9670 	}*/
9671 	if (m_Doc && m_Doc->isLoading())
9672 	{
9673 		m_imageXOffset = imgXOffs;
9674 		m_imageYOffset = imgYOffs;
9675 	}
9676 	if (!imageClip.empty())
9677 	{
9678 		imageClip = pixm.imgInfo.PDSpathData[pixm.imgInfo.usedPath].copy();
9679 		QTransform cl;
9680 		cl.translate(m_imageXOffset*m_imageXScale, m_imageYOffset*m_imageYScale);
9681 		cl.scale(m_imageXScale, m_imageYScale);
9682 		imageClip.map(cl);
9683 	}
9684 }
9685 
setExternalFile(const QString & filename,const QString & baseDir)9686 void PageItem::setExternalFile(const QString& filename, const QString& baseDir)
9687 {
9688 	Pfile = filename;
9689 	if (Pfile.isEmpty())
9690 		return;
9691 
9692 	QString test = Pfile;
9693 	if (QDir::isRelativePath(test))
9694 	{
9695 		if (baseDir.isEmpty())
9696 			test = QDir::homePath() + "/" + Pfile;
9697 		else
9698 			test = baseDir + "/" + Pfile;
9699 	}
9700 	test = QDir::cleanPath(QDir::toNativeSeparators(test));
9701 	QFileInfo pfi2(test);
9702 	Pfile = pfi2.absoluteFilePath();
9703 }
9704 
setFileIconPressed(const QString & filename,const QString & baseDir)9705 void PageItem::setFileIconPressed(const QString& filename, const QString& baseDir)
9706 {
9707 	Pfile2 = filename;
9708 	if (Pfile2.isEmpty())
9709 		return;
9710 
9711 	QString test = Pfile2;
9712 	if (QDir::isRelativePath(test))
9713 	{
9714 		if (baseDir.isEmpty())
9715 			test = QDir::homePath() + "/" + Pfile2;
9716 		else
9717 			test = baseDir + "/" + Pfile2;
9718 	}
9719 	test = QDir::cleanPath(QDir::toNativeSeparators(test));
9720 	QFileInfo pfi2(test);
9721 	Pfile2 = pfi2.absoluteFilePath();
9722 }
9723 
setFileIconRollover(const QString & filename,const QString & baseDir)9724 void PageItem::setFileIconRollover(const QString& filename, const QString& baseDir)
9725 {
9726 	Pfile3 = filename;
9727 	if (Pfile3.isEmpty())
9728 		return;
9729 
9730 	QString test = Pfile3;
9731 	if (QDir::isRelativePath(test))
9732 	{
9733 		if (baseDir.isEmpty())
9734 			test = QDir::homePath() + "/" + Pfile3;
9735 		else
9736 			test = baseDir + "/" + Pfile3;
9737 	}
9738 	test = QDir::cleanPath(QDir::toNativeSeparators(test));
9739 	QFileInfo pfi2(test);
9740 	Pfile3 = pfi2.absoluteFilePath();
9741 }
9742 
firstInChain()9743 PageItem* PageItem::firstInChain()
9744 {
9745 	//huh? Q_ASSERT(this != nullptr);
9746 	PageItem* first = this;
9747 	while (first->prevInChain() != nullptr)
9748 		first = first->prevInChain();
9749 	return first;
9750 }
9751 
lastInChain()9752 PageItem* PageItem::lastInChain()
9753 {
9754 	//huh? Q_ASSERT(this != nullptr);
9755 	PageItem* last = this;
9756 	while (last->nextInChain() != nullptr)
9757 		last = last->nextInChain();
9758 	return last;
9759 }
9760 
lastInChainSamePage()9761 PageItem* PageItem::lastInChainSamePage()
9762 {
9763 	//huh? Q_ASSERT(this != nullptr);
9764 	PageItem* last = this;
9765 	while (last->OwnPage != OwnPage && last->nextInChain() != nullptr)
9766 		last = last->nextInChain();
9767 	return last;
9768 }
9769 
getRedrawBounding(double viewScale) const9770 QRect PageItem::getRedrawBounding(double viewScale) const
9771 {
9772 	double maxLineWidth = qMax(m_lineWidth, m_oldLineWidth);
9773 	QRectF boundingRect(-maxLineWidth / 2.0 - 5 / viewScale,
9774 	                    -maxLineWidth / 2.0 - 5 / viewScale,
9775 	                    BoundingW + maxLineWidth + 10 / viewScale,
9776 	                    BoundingH + maxLineWidth + 10 / viewScale);
9777 	QTransform t = getTransform();
9778 	boundingRect = t.mapRect(boundingRect);
9779 
9780 	QRectF redrawBoundingF((boundingRect.x() - m_Doc->minCanvasCoordinate.x()) * viewScale,
9781 	                       (boundingRect.y() - m_Doc->minCanvasCoordinate.y()) * viewScale,
9782 	                        boundingRect.width() * viewScale,
9783 	                        boundingRect.height() * viewScale);
9784 	redrawBoundingF = redrawBoundingF.normalized();
9785 
9786 	int x = floor(redrawBoundingF.left());
9787 	int y = floor(redrawBoundingF.top());
9788 	int w = ceil(redrawBoundingF.right()) - x;
9789 	int h = ceil(redrawBoundingF.bottom()) - y;
9790 	return QRect(x, y, w, h);
9791 }
9792 
setRedrawBounding()9793 void PageItem::setRedrawBounding()
9794 {
9795 	double bw, bh;
9796 	getBoundingRect(&BoundingX, &BoundingY, &bw, &bh);
9797 	BoundingW = bw - BoundingX;
9798 	BoundingH = bh - BoundingY;
9799 	if (asLine())
9800 		BoundingH = qMax(BoundingH, 1.0);
9801 }
9802 
updateGradientVectors()9803 void PageItem::updateGradientVectors()
9804 {
9805 	switch (GrType)
9806 	{
9807 		case Gradient_None:
9808 		case Gradient_LinearLegacy1:
9809 			setGradientStart(0.0, m_height / 2.0);
9810 			setGradientEnd(m_width, m_height / 2.0);
9811 			break;
9812 		case Gradient_LinearLegacy2:
9813 			setGradientStart(m_width / 2.0, 0.0);
9814 			setGradientEnd(m_width / 2.0, m_height);
9815 			break;
9816 		case Gradient_LinearLegacy3:
9817 			setGradientStart(0.0, 0.0);
9818 			setGradientEnd(m_width, m_height);
9819 			break;
9820 		case Gradient_LinearLegacy4:
9821 			setGradientStart(0.0, m_height);
9822 			setGradientEnd(m_width, 0.0);
9823 			break;
9824 		case Gradient_RadialLegacy5:
9825 			setGradientStart(m_width / 2.0, m_height / 2.0);
9826 			if (m_width >= m_height)
9827 				setGradientEnd(m_width, m_height / 2.0);
9828 			else
9829 				setGradientEnd(m_width / 2.0, m_height);
9830 			break;
9831 		default:
9832 			break;
9833 	}
9834 	//if (ScMW->view->SelItem.count()!=0 && this==ScMW->view->SelItem.at(0))
9835 	//if (m_Doc->m_Selection->count()!=0 && m_Doc->m_Selection->primarySelectionIsMyself(this))
9836 	//	ScMW->propertiesPalette->updateColorSpecialGradient();
9837 	//CB Will only emit if connected, ie is first in GUI selection
9838 	//unused double dur=m_Doc->unitRatio();
9839 }
9840 
setPolyClip(int up,int down)9841 void PageItem::setPolyClip(int up, int down)
9842 {
9843 	if (PoLine.size() < 3)
9844 		return;
9845 	double rot;
9846 	int upval = up;
9847 	int downval = down;
9848 	if (up == 0)
9849 		upval = 1;
9850 	if (textPathFlipped)
9851 	{
9852 		upval *= -1;
9853 		downval *= -1;
9854 	}
9855 	QPoint np, np2;
9856 	QPolygon cl, cl1, cl2;
9857 	Segments.clear();
9858 	QPainterPath pa = PoLine.toQPainterPath(false);
9859 	QList<QPolygonF> polist = pa.toSubpathPolygons();
9860 	for (int i = 0; i < polist.count(); i++)
9861 	{
9862 		QPolygon cli = polist[i].toPolygon();
9863 		cl += cli;
9864 		Segments.append(cl.size());
9865 	}
9866 	if (cl.size() > 1)
9867 	{
9868 		Clip.resize(0);
9869 		for (int i = 0; i < cl.size() - 1; ++i)
9870 		{
9871 			rot = xy2Deg(cl.point(i + 1).x() - cl.point(i).x(), cl.point(i + 1).y() - cl.point(i).y());
9872 			QTransform ma;
9873 			ma.rotate(rot);
9874 			np = QPoint(0, -upval) * ma;
9875 			np2 = QPoint(0, -downval) * ma;
9876 			cl1.resize(cl1.size() + 1);
9877 			cl1.setPoint(cl1.size() - 1, np+cl.point(i));
9878 			cl1.resize(cl1.size() + 1);
9879 			cl1.setPoint(cl1.size() - 1, np + cl.point(i + 1));
9880 			cl2.resize(cl2.size() + 1);
9881 			cl2.setPoint(cl2.size() - 1, np2 + cl.point(i));
9882 			cl2.resize(cl2.size() + 1);
9883 			cl2.setPoint(cl2.size() - 1, np2 + cl.point(i + 1));
9884 		}
9885 		cl1.resize(cl1.size() + 1);
9886 		cl1.setPoint(cl1.size() - 1, np + cl.point(cl.size() - 1));
9887 		cl2.resize(cl2.size()+1);
9888 		cl2.setPoint(cl2.size() - 1, np2 + cl.point(cl.size() - 1));
9889 		Clip.putPoints(Clip.size(), cl1.size(), cl1);
9890 		for (int i2 = cl2.size() - 1; i2 > -1; i2--)
9891 		{
9892 			Clip.resize(Clip.size() + 1);
9893 			Clip.setPoint(Clip.size() - 1, cl2.point(i2));
9894 		}
9895 	}
9896 }
9897 
updatePolyClip()9898 void PageItem::updatePolyClip()
9899 {
9900 	int asce = 1;
9901 	int desc = 1;
9902 	int itemTextCount = itemText.length();
9903 	for (int i = 0; i < itemTextCount; ++i)
9904 	{
9905 		const CharStyle& hl (itemText.charStyle(i));
9906 		int des = static_cast<int>(hl.font().descent(hl.fontSize() / 10.0));
9907 		int asc = static_cast<int>(hl.font().ascent(hl.fontSize() / 10.0));
9908 		asce = qMax(asce, asc);
9909 		desc = qMax(desc, des);
9910 	}
9911 	setPolyClip(static_cast<int>(asce - BaseOffs), static_cast<int>(desc - BaseOffs));
9912 }
9913 
handleModeEditKey(QKeyEvent *,bool &)9914 void PageItem::handleModeEditKey(QKeyEvent * /* k */, bool & /* keyRepeat */)
9915 {
9916 }
9917 
connectToGUI()9918 bool PageItem::connectToGUI()
9919 {
9920 	if (!ScCore->usingGUI())
9921 		return false;
9922 	if (!m_Doc->m_Selection->primarySelectionIs(this))
9923 		return false;
9924 
9925 	connect(this, SIGNAL(frameType(int)), m_Doc->scMW(), SLOT(HaveNewSel()), Qt::UniqueConnection);
9926 	connect(this, SIGNAL(frameType(int)), m_Doc, SLOT(selectionChanged()), Qt::UniqueConnection);
9927 	connect(this, SIGNAL(textStyle(int)), m_Doc->scMW(), SLOT(setStyleEffects(int)), Qt::UniqueConnection);
9928 
9929 	return true;
9930 }
9931 
disconnectFromGUI()9932 bool PageItem::disconnectFromGUI()
9933 {
9934 	if (!ScCore->usingGUI())
9935 		return false;
9936 	// Disconnecting only signals from PP will leave some remaining connections
9937 	// and cause progressive slowdowns
9938 	// PropertiesPalette* pp=m_Doc->scMW()->propertiesPalette;
9939 	// disconnect(this, 0, pp, 0);
9940 	this->disconnect();
9941 	return true;
9942 }
9943 
emitAllToGUI()9944 void PageItem::emitAllToGUI()
9945 {
9946 	updateConstants();
9947 
9948 	emit myself(this);
9949 	emit frameType(m_itemType);
9950 
9951 //CB unused in 135
9952 //	double dur=m_Doc->unitRatio();
9953 //	emit blendmode(m_fillBlendMode, m_lineBlendMode);
9954 /*CB using the emit myself* instead of all of these
9955 	emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
9956 */
9957 	if (m_Doc->appMode != modeEdit)
9958 	{
9959 //TODO remove and use the emit myself
9960 		//emit lineSpacing(itemText.defaultStyle().lineSpacing());
9961 		//emit textKerning(itemText.defaultStyle().charStyle().tracking());
9962 		emit textStyle(itemText.defaultStyle().charStyle().effects());
9963 		//emit textFont(itemText.defaultStyle().charStyle().font().scName());
9964 		//emit textSize(itemText.defaultStyle().charStyle().fontSize());
9965 //		emit textFormatting(itemText.defaultStyle().alignment());
9966 	}
9967 }
9968 
setIsAnnotation(bool isAnnot)9969 void PageItem::setIsAnnotation(bool isAnnot)
9970 {
9971 	if (m_isAnnotation==isAnnot)
9972 		return; // nothing to do -> return
9973 	if (UndoManager::undoEnabled())
9974 	{
9975 		SimpleState *ss = new SimpleState(Um::ActionPDF, nullptr, Um::IGroup);
9976 		ss->set("ACTIONPDFANNOTATION", isAnnot);
9977 		undoManager->action(this, ss);
9978 	}
9979 	m_isAnnotation=isAnnot;
9980 }
9981 
setIsBookMark(bool isBM)9982 void PageItem::setIsBookMark(bool isBM)
9983 {
9984 	if (isBookmark == isBM)
9985 		return; // nothing to do -> return
9986 	if (UndoManager::undoEnabled())
9987 	{
9988 		SimpleState *ss = new SimpleState(Um::ActionPDF, nullptr, Um::IGroup);
9989 		ss->set("ACTIONPDFBOOKMARK", isBM);
9990 		undoManager->action(this, ss);
9991 	}
9992 	isBookmark = isBM;
9993 }
9994 
setResolution(int id)9995 void PageItem::setResolution(int id)
9996 {
9997 	if (pixm.imgInfo.lowResType == id)
9998 		return;
9999 	if (UndoManager::undoEnabled())
10000 	{
10001 		SimpleState *ss = new SimpleState(Um::ResTyp, QString(), Um::IImageFrame);
10002 		ss->set("RES_TYP");
10003 		ss->set("OLD_RES",pixm.imgInfo.lowResType);
10004 		ss->set("NEW_RES",id);
10005 		undoManager->action(this, ss);
10006 	}
10007 	pixm.imgInfo.lowResType = id;
10008 }
10009 
setAnnotation(const Annotation & ad)10010 void PageItem::setAnnotation(const Annotation& ad)
10011 {
10012 	m_annotation = ad;
10013 }
10014 
setImageVisible(bool isShown)10015 void PageItem::setImageVisible(bool isShown)
10016 {
10017 	if (m_imageVisible == isShown)
10018 		return;
10019 	if (UndoManager::undoEnabled())
10020 	{
10021 		SimpleState *ss = new SimpleState(Um::ResTyp, QString(), Um::IImageFrame);
10022 		ss->set("SHOW_IMAGE");
10023 		ss->set("OLD", m_imageVisible);
10024 		undoManager->action(this, ss);
10025 	}
10026 	m_imageVisible=isShown;
10027 }
10028 
updateConstants()10029 void PageItem::updateConstants()
10030 {
10031 	m_Doc->constants().insert("width", m_width);
10032 	m_Doc->constants().insert("height", m_height);
10033 }
10034 
10035 //CB Old ScribusView MoveItemI
moveImageInFrame(double newX,double newY)10036 void PageItem::moveImageInFrame(double newX, double newY)
10037 {
10038 	if (m_itemType != PageItem::ImageFrame)
10039 		return;
10040 	if (locked())// || (!ScaleType))
10041 		return;
10042 	double dX=0.0, dY=0.0;
10043 	if (imageFlippedH())
10044 		dX = -newX;
10045 	else
10046 		dX = newX;
10047 	if (imageFlippedV())
10048 		dY = -newY;
10049 	else
10050 		dY = newY;
10051 	moveImageXYOffsetBy(dX, dY);
10052 	if (!imageClip.empty())
10053 	{
10054 		imageClip = pixm.imgInfo.PDSpathData[pixm.imgInfo.usedPath].copy();
10055 		QTransform cl;
10056 		cl.translate(imageXOffset() * imageXScale(), imageYOffset() * imageYScale());
10057 		cl.rotate(imageRotation());
10058 		cl.scale(imageXScale(), imageYScale());
10059 		imageClip.map(cl);
10060 	}
10061 }
10062 
convertClip()10063 void PageItem::convertClip()
10064 {
10065 	if (Clip.count() != 0)
10066 	{
10067 		FPoint np(Clip.point(0));
10068 		PoLine.resize(2);
10069 		PoLine.setPoint(0, np);
10070 		PoLine.setPoint(1, np);
10071 		for (int a = 1; a < Clip.size(); ++a)
10072 		{
10073 			np = FPoint(Clip.point(a));
10074 			PoLine.putPoints(PoLine.size(), 4, np.x(), np.y(), np.x(), np.y(), np.x(), np.y(), np.x(), np.y());
10075 		}
10076 		np = FPoint(Clip.point(0));
10077 		PoLine.putPoints(PoLine.size(), 2, np.x(), np.y(), np.x(), np.y());
10078 		Clip = flattenPath(PoLine, Segments);
10079 	}
10080 	else
10081 	{
10082 		SetRectFrame();
10083 		m_Doc->setRedrawBounding(this);
10084 	}
10085 }
10086 
10087 //udateWelded determine if welded items should be updated as well (default behaviour)
updateClip(bool updateWelded)10088 void PageItem::updateClip(bool updateWelded)
10089 {
10090 	if (m_Doc->appMode == modeDrawBezierLine)
10091 		return;
10092 	if (ContourLine.empty())
10093 		ContourLine = PoLine.copy();
10094 //	int ph = static_cast<int>(qMax(1.0, lineWidth() / 2.0));
10095 	bool clipBackup = ClipEdited;
10096 	switch (itemType())
10097 	{
10098 	case PageItem::Line:
10099 		{
10100 			PageItem_Line* lineItem = asLine();
10101 			if (lineItem)
10102 				lineItem->setLineClip();
10103 		}
10104 		break;
10105 	default:
10106 		if (((!ClipEdited) || (FrameType < 3)) && !(asPathText()))
10107 		{
10108 			switch (FrameType)
10109 			{
10110 			case 0:
10111 				SetRectFrame();
10112 				m_Doc->setRedrawBounding(this);
10113 				break;
10114 			case 1:
10115 				SetOvalFrame();
10116 				m_Doc->setRedrawBounding(this);
10117 				break;
10118 			case 2:
10119 				//CB FIXME: stop using nodeEdit.clre or move out of here
10120 				m_Doc->nodeEdit.deselect();
10121 				SetFrameRound();
10122 				m_Doc->setRedrawBounding(this);
10123 				break;
10124 			default:
10125 				break;
10126 			}
10127 			ClipEdited = clipBackup;
10128 			if ((OldB2 != 0) && (OldH2 != 0) && (width() != 0) && (height() != 0))
10129 			{
10130 				double scx = width() / OldB2;
10131 				double scy = height() / OldH2;
10132 				QTransform ma;
10133 				ma.scale(scx, scy);
10134 				FPointArray gr;
10135 				gr.addPoint(GrStartX, GrStartY);
10136 				gr.addPoint(GrEndX, GrEndY);
10137 				gr.addPoint(GrFocalX, GrFocalY);
10138 				gr.addPoint(GrControl1);
10139 				gr.addPoint(GrControl2);
10140 				gr.addPoint(GrControl3);
10141 				gr.addPoint(GrControl4);
10142 				gr.addPoint(GrControl5);
10143 				gr.map(ma);
10144 				for (int grow = 0; grow < meshGradientArray.count(); grow++)
10145 				{
10146 					for (int gcol = 0; gcol < meshGradientArray[grow].count(); gcol++)
10147 					{
10148 						meshGradientArray[grow][gcol].transform(ma);
10149 					}
10150 				}
10151 				for (int col = 0; col < meshGradientPatches.count(); col++)
10152 				{
10153 					meshGradientPatches[col].TL.transform(ma);
10154 					meshGradientPatches[col].TR.transform(ma);
10155 					meshGradientPatches[col].BL.transform(ma);
10156 					meshGradientPatches[col].BR.transform(ma);
10157 				}
10158 				GrStartX = gr.point(0).x();
10159 				GrStartY = gr.point(0).y();
10160 				GrEndX = gr.point(1).x();
10161 				GrEndY = gr.point(1).y();
10162 				GrFocalX = gr.point(2).x();
10163 				GrFocalY = gr.point(2).y();
10164 				GrControl1 = gr.point(3);
10165 				GrControl2 = gr.point(4);
10166 				GrControl3 = gr.point(5);
10167 				GrControl4 = gr.point(6);
10168 				GrControl5 = gr.point(7);
10169 				FPointArray gr2;
10170 				gr2.addPoint(GrStrokeStartX, GrStrokeStartY);
10171 				gr2.addPoint(GrStrokeEndX, GrStrokeEndY);
10172 				gr2.addPoint(GrStrokeFocalX, GrStrokeFocalY);
10173 				gr2.map(ma);
10174 				GrStrokeStartX = gr2.point(0).x();
10175 				GrStrokeStartY = gr2.point(0).y();
10176 				GrStrokeEndX = gr2.point(1).x();
10177 				GrStrokeEndY = gr2.point(1).y();
10178 				GrStrokeFocalX = gr2.point(2).x();
10179 				GrStrokeFocalY = gr2.point(2).y();
10180 				FPointArray gr3;
10181 				gr3.addPoint(GrMaskStartX, GrMaskStartY);
10182 				gr3.addPoint(GrMaskEndX, GrMaskEndY);
10183 				gr3.addPoint(GrMaskFocalX, GrMaskFocalY);
10184 				gr3.map(ma);
10185 				GrMaskStartX = gr3.point(0).x();
10186 				GrMaskStartY = gr3.point(0).y();
10187 				GrMaskEndX = gr3.point(1).x();
10188 				GrMaskEndY = gr3.point(1).y();
10189 				GrMaskFocalX = gr3.point(2).x();
10190 				GrMaskFocalY = gr3.point(2).y();
10191 				ContourLine.map(ma);
10192 				if (FrameType > 2)
10193 				{
10194 					PoLine.map(ma);
10195 					if (asPathText())
10196 						updatePolyClip();
10197 					else
10198 						Clip = flattenPath(PoLine, Segments);
10199 				}
10200 				if (updateWelded)
10201 				{
10202 					for (int i = 0 ; i < weldList.count(); i++)
10203 					{
10204 						WeldingInfo wInf = weldList.at(i);
10205 						if (!wInf.weldItem)
10206 							continue;
10207 						if (wInf.weldItem->isNoteFrame())
10208 						{
10209 							PageItem_NoteFrame* noteFrame = wInf.weldItem->asNoteFrame();
10210 							if (noteFrame->notesStyle()->isAutoWeldNotesFrames())
10211 							{
10212 								if (noteFrame->notesStyle()->isAutoNotesWidth())
10213 								{
10214 									if (noteFrame->width() != width())
10215 									{
10216 										noteFrame->setWidth(width());
10217 										noteFrame->updateClip();
10218 									}
10219 								}
10220 								noteFrame->setXYPos(xPos(),yPos() + height());
10221 								setWeldPoint(0, height(), noteFrame);
10222 								noteFrame->setWeldPoint(0,0, this);
10223 								continue;
10224 							}
10225 						}
10226 						FPointArray gr4;
10227 						FPoint wp = wInf.weldPoint;
10228 						gr4.addPoint(wp);
10229 						gr4.map(ma);
10230 						double dx = gr4.point(0).x() - wp.x();
10231 						double dy = gr4.point(0).y() - wp.y();
10232 						moveWelded(dx, dy, i);
10233 						wInf.weldPoint = gr4.point(0);
10234 						weldList[i] = wInf;
10235 					}
10236 				}
10237 			}
10238 			OldB2 = width();
10239 			OldH2 = height();
10240 			if ((FrameType < 3) && (!ClipEdited))
10241 				ContourLine = PoLine.copy();
10242 		}
10243 		else
10244 		{
10245 			if (m_Doc->SubMode != -1)
10246 			{
10247 				switch (m_Doc->SubMode)
10248 				{
10249 				case 0:
10250 					SetRectFrame();
10251 					m_Doc->setRedrawBounding(this);
10252 					break;
10253 				case 1:
10254 					SetOvalFrame();
10255 					m_Doc->setRedrawBounding(this);
10256 					break;
10257 				default:
10258 					SetFrameShape(m_Doc->ValCount, m_Doc->ShapeValues);
10259 					m_Doc->setRedrawBounding(this);
10260 					break;
10261 				}
10262 				OldB2 = width();
10263 				OldH2 = height();
10264 				ContourLine = PoLine.copy();
10265 			}
10266 			OldB2 = (OldB2 == 0) ? 1 : OldB2;
10267 			OldH2 = (OldH2 == 0) ? 1 : OldH2;
10268 			double scx = width() / OldB2;
10269 			double scy = height() / OldH2;
10270 			QTransform ma;
10271 			ma.scale(scx, scy);
10272 			FPointArray gr;
10273 			gr.addPoint(GrStartX, GrStartY);
10274 			gr.addPoint(GrEndX, GrEndY);
10275 			gr.addPoint(GrFocalX, GrFocalY);
10276 			gr.addPoint(GrControl1);
10277 			gr.addPoint(GrControl2);
10278 			gr.addPoint(GrControl3);
10279 			gr.addPoint(GrControl4);
10280 			gr.addPoint(GrControl5);
10281 			gr.map(ma);
10282 			for (int grow = 0; grow < meshGradientArray.count(); grow++)
10283 			{
10284 				for (int gcol = 0; gcol < meshGradientArray[grow].count(); gcol++)
10285 				{
10286 					meshGradientArray[grow][gcol].transform(ma);
10287 				}
10288 			}
10289 			for (int col = 0; col < meshGradientPatches.count(); col++)
10290 			{
10291 				meshGradientPatches[col].TL.transform(ma);
10292 				meshGradientPatches[col].TR.transform(ma);
10293 				meshGradientPatches[col].BL.transform(ma);
10294 				meshGradientPatches[col].BR.transform(ma);
10295 			}
10296 			GrStartX = gr.point(0).x();
10297 			GrStartY = gr.point(0).y();
10298 			GrEndX = gr.point(1).x();
10299 			GrEndY = gr.point(1).y();
10300 			GrFocalX = gr.point(2).x();
10301 			GrFocalY = gr.point(2).y();
10302 			GrControl1 = gr.point(3);
10303 			GrControl2 = gr.point(4);
10304 			GrControl3 = gr.point(5);
10305 			GrControl4 = gr.point(6);
10306 			GrControl5 = gr.point(7);
10307 			FPointArray gr2;
10308 			gr2.addPoint(GrStrokeStartX, GrStrokeStartY);
10309 			gr2.addPoint(GrStrokeEndX, GrStrokeEndY);
10310 			gr2.addPoint(GrStrokeFocalX, GrStrokeFocalY);
10311 			gr2.map(ma);
10312 			GrStrokeStartX = gr2.point(0).x();
10313 			GrStrokeStartY = gr2.point(0).y();
10314 			GrStrokeEndX = gr2.point(1).x();
10315 			GrStrokeEndY = gr2.point(1).y();
10316 			GrStrokeFocalX = gr2.point(2).x();
10317 			GrStrokeFocalY = gr2.point(2).y();
10318 			FPointArray gr3;
10319 			gr3.addPoint(GrMaskStartX, GrMaskStartY);
10320 			gr3.addPoint(GrMaskEndX, GrMaskEndY);
10321 			gr3.addPoint(GrMaskFocalX, GrMaskFocalY);
10322 			gr3.map(ma);
10323 			GrMaskStartX = gr3.point(0).x();
10324 			GrMaskStartY = gr3.point(0).y();
10325 			GrMaskEndX = gr3.point(1).x();
10326 			GrMaskEndY = gr3.point(1).y();
10327 			GrMaskFocalX = gr3.point(2).x();
10328 			GrMaskFocalY = gr3.point(2).y();
10329 			PoLine.map(ma);
10330 			ContourLine.map(ma);
10331 			if (asPathText())
10332 				updatePolyClip();
10333 			else
10334 				Clip = flattenPath(PoLine, Segments);
10335 			OldB2 = width();
10336 			OldH2 = height();
10337 			if (updateWelded)
10338 			{
10339 				for (int i = 0 ; i < weldList.count(); i++)
10340 				{
10341 					WeldingInfo wInf = weldList.at(i);
10342 					if (wInf.weldItem->isNoteFrame())
10343 					{
10344 						PageItem_NoteFrame* noteFrame = wInf.weldItem->asNoteFrame();
10345 						if (noteFrame->notesStyle()->isAutoWeldNotesFrames())
10346 						{
10347 							if (noteFrame->notesStyle()->isAutoNotesWidth())
10348 							{
10349 								if (noteFrame->width() != width())
10350 								{
10351 									noteFrame->setWidth(width());
10352 									noteFrame->updateClip();
10353 								}
10354 							}
10355 							setWeldPoint(0, height(), noteFrame);
10356 							noteFrame->setWeldPoint(0,0, this);
10357 							continue;
10358 						}
10359 					}
10360 					FPointArray gr4;
10361 					FPoint wp = wInf.weldPoint;
10362 					gr4.addPoint(wp);
10363 					gr4.map(ma);
10364 					double dx = gr4.point(0).x() - wp.x();
10365 					double dy = gr4.point(0).y() - wp.y();
10366 					moveWelded(dx, dy, i);
10367 					wInf.weldPoint = gr4.point(0);
10368 					weldList[i] = wInf;
10369 				}
10370 			}
10371 		}
10372 		break;
10373 	}
10374 	updateGradientVectors();
10375 }
10376 
infoDescription() const10377 QString PageItem::infoDescription() const
10378 {
10379 	QString htmlText;
10380 	htmlText.append(ScribusView::tr("Print: "));
10381 	if (printEnabled())
10382 		htmlText.append(ScribusView::tr("Enabled"));
10383 	else
10384 		htmlText.append(ScribusView::tr("Disabled"));
10385 	htmlText.append("<br/>");
10386 	return htmlText;
10387 }
10388 
firstLineOffset() const10389 FirstLineOffsetPolicy PageItem::firstLineOffset() const
10390 {
10391 	return m_firstLineOffset;
10392 }
10393 
setFirstLineOffset(FirstLineOffsetPolicy flop)10394 void PageItem::setFirstLineOffset(FirstLineOffsetPolicy flop)
10395 {
10396 	if (m_firstLineOffset == flop)
10397 		return;
10398 
10399 	if (UndoManager::undoEnabled())
10400 	{
10401 		ScItemState<QPair<FirstLineOffsetPolicy,FirstLineOffsetPolicy> > *is = new ScItemState<QPair <FirstLineOffsetPolicy,FirstLineOffsetPolicy> >(Um::FirstLineOffset);
10402 		is->set("FIRSTLINEOFFSET");
10403 		is->setItem(qMakePair(m_firstLineOffset, flop));
10404 		undoManager->action(this, is);
10405 	}
10406 	m_firstLineOffset = flop;
10407 }
10408 
setInlineData(const QString & data)10409 void PageItem::setInlineData(const QString& data)
10410 {
10411 	QByteArray inlineImageData;
10412 	inlineImageData.append(data.toUtf8());
10413 	if (inlineImageData.size() > 0)
10414 	{
10415 		QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + inlineExt);
10416 		tempFile->setAutoRemove(false);
10417 		tempFile->open();
10418 		QString fileName = getLongPathName(tempFile->fileName());
10419 		tempFile->close();
10420 		inlineImageData = qUncompress(QByteArray::fromBase64(inlineImageData));
10421 		QFile outFil(fileName);
10422 		if (outFil.open(QIODevice::WriteOnly))
10423 		{
10424 			outFil.write(inlineImageData);
10425 			outFil.close();
10426 			isInlineImage = true;
10427 			isTempFile = true;
10428 			Pfile = fileName;
10429 			delete tempFile;
10430 		}
10431 	}
10432 }
10433 
makeImageInline()10434 void PageItem::makeImageInline()
10435 {
10436 	QFileInfo fi(Pfile);
10437 	QString ext = fi.suffix();
10438 	QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + ext);
10439 	tempFile->setAutoRemove(false);
10440 	tempFile->open();
10441 	QString fileName = getLongPathName(tempFile->fileName());
10442 	tempFile->close();
10443 	isInlineImage = true;
10444 	isTempFile = true;
10445 	copyFile(Pfile, fileName);
10446 	Pfile = QDir::fromNativeSeparators(fileName);
10447 	delete tempFile;
10448 }
10449 
makeImageExternal(const QString & path)10450 void PageItem::makeImageExternal(const QString& path)
10451 {
10452 	if ((isTempFile) && (isInlineImage) && (!path.isEmpty()))
10453 	{
10454 		QString oldF = Pfile;
10455 		copyFile(Pfile, path);
10456 		Pfile = path;
10457 		QFile::remove(oldF);
10458 		isInlineImage = false;
10459 		isTempFile = false;
10460 	}
10461 }
10462 
addWelded(PageItem * item)10463 void PageItem::addWelded(PageItem* item)
10464 {
10465 	FPoint centerI = FPoint(xPos() + (width() / 2.0), yPos() + (height() / 2.0));
10466 	FPoint centerP = FPoint(item->xPos() + (item->width() / 2.0), item->yPos() + (item->height() / 2.0));
10467 	WeldingInfo wInf;
10468 	wInf.weldItem = item;
10469 	wInf.weldPoint = FPoint((width() / 2.0) + ((centerP.x() - centerI.x()) / 2.0), (height() / 2.0) + ((centerP.y() - centerI.y()) / 2.0));
10470 	weldList.append(wInf);
10471 }
10472 
10473 //welded frames
weldTo(PageItem * item)10474 void PageItem::weldTo(PageItem* item)
10475 {
10476 	UndoTransaction activeTransaction;
10477 	if (undoManager->undoEnabled())
10478 		activeTransaction = undoManager->beginTransaction(Um::WeldItems + "/" + Um::Selection, Um::IGroup,
10479 														  Um::WeldItems, QString(), Um::IGroup);
10480 	for (int i = 0 ; i <  weldList.count(); i++)
10481 	{
10482 		PageItem::WeldingInfo wInf = weldList.at(i);
10483 		if (wInf.weldItem == item)
10484 			return;
10485 	}
10486 	QList<PageItem*> weldItems = item->itemsWeldedTo();
10487 	if (weldItems.contains(this))
10488 		return;
10489 	addWelded(item);
10490 	item->addWelded(this);
10491 	if (undoManager->undoEnabled())
10492 	{
10493 		ScItemState<PageItem*> *is = new ScItemState<PageItem*>(Um::WeldItems, QString(), Um::IGroup);
10494 		is->set("WELD_ITEMS");
10495 		is->setItem(item);
10496 		undoManager->action(this, is, getUPixmap());
10497 	}
10498 	update();
10499 	item->update();
10500 	if (activeTransaction)
10501 		activeTransaction.commit();
10502 }
10503 
moveWelded(double dX,double dY,int weld)10504 void PageItem::moveWelded(double dX, double dY, int weld)
10505 {
10506 	WeldingInfo wInf = weldList.at(weld);
10507 	PageItem *item = wInf.weldItem;
10508 	item->setXPos(item->xPos() + dX);
10509 	item->setYPos(item->yPos() + dY);
10510 	item->update();
10511 	item->moveWelded(dX, dY, this);
10512 }
10513 
moveWelded(double dX,double dY,PageItem * except)10514 void PageItem::moveWelded(double dX, double dY, PageItem* except)
10515 {
10516 	//qDebug()<<"PageItem::moveWelded"<<dX<<dY;
10517 	if ((dX == 0) && (dY == 0))
10518 		return;
10519 	//do not save undo for auto-welded notes frames
10520 	UndoManager::instance()->setUndoEnabled(false);
10521 	for (int i = 0 ; i < weldList.count(); i++)
10522 	{
10523 		WeldingInfo wInf = weldList.at(i);
10524 		PageItem *item = wInf.weldItem;
10525 		if (item != except)
10526 		{
10527 			item->setXPos(item->xPos() + dX);
10528 			item->setYPos(item->yPos() + dY);
10529 			item->update();
10530 			item->moveWelded(dX, dY, this);
10531 		}
10532 	}
10533 	UndoManager::instance()->setUndoEnabled(true);
10534 }
10535 
rotateWelded(double dR,double oldRot)10536 void PageItem::rotateWelded(double dR, double oldRot)
10537 {
10538 	UndoManager::instance()->setUndoEnabled(false);
10539 	QTransform ma;
10540 	ma.translate(xPos(), yPos());
10541 	ma.scale(1, 1);
10542 	ma.rotate(oldRot);
10543 	switch (m_Doc->rotationMode())
10544 	{
10545 		case 2:
10546 			ma.translate(width()/2.0, height()/2.0);
10547 			break;
10548 		case 4:
10549 			ma.translate(width(), height());
10550 			break;
10551 		case 3:
10552 			ma.translate(0, height());
10553 			break;
10554 		case 1:
10555 			ma.translate(width(), 0);
10556 			break;
10557 	}
10558 	QPointF rotCenter = ma.map(QPointF(0,0));
10559 	QList<PageItem*> itemList = itemsWeldedTo(this);
10560 	for (int i = 0; i < itemList.count(); i++)
10561 	{
10562 		PageItem *item = itemList.at(i);
10563 		QLineF lin = QLineF(rotCenter, QPointF(item->xPos(), item->yPos()));
10564 		lin.setAngle(lin.angle() - dR);
10565 		item->setXYPos(lin.p2().x(), lin.p2().y());
10566 		item->rotateBy(dR);
10567 	}
10568 	UndoManager::instance()->setUndoEnabled(true);
10569 }
10570 
itemsWeldedTo(PageItem * except)10571 QList<PageItem*> PageItem::itemsWeldedTo(PageItem* except)
10572 {
10573 	QList<PageItem*> pageItemList;
10574 	for (int i = 0 ; i < weldList.count(); i++)
10575 	{
10576 		WeldingInfo wInf = weldList.at(i);
10577 		PageItem *item = wInf.weldItem;
10578 		if (item != except)
10579 		{
10580 			pageItemList.append(item);
10581 			if (item->isWelded())
10582 				pageItemList.append(item->itemsWeldedTo(this));
10583 		}
10584 	}
10585 	return pageItemList;
10586 }
10587 
setWeldPoint(double dX,double dY,PageItem * pItem)10588 void PageItem::setWeldPoint(double dX, double dY, PageItem *pItem)
10589 {
10590 	for (int i = 0 ; i < weldList.count(); i++)
10591 	{
10592 		PageItem *item = weldList[i].weldItem;
10593 		if (item == pItem)
10594 		{
10595 			weldList[i].weldPoint = FPoint(dX, dY);
10596 			return;
10597 		}
10598 	}
10599 }
10600 
unWeld()10601 void PageItem::unWeld()
10602 {
10603 	UndoTransaction activeTransaction;
10604 	if (undoManager->undoEnabled())
10605 		activeTransaction = undoManager->beginTransaction(Um::UnweldItems + "/" + Um::Selection, Um::IGroup,
10606 														  Um::UnweldItems, QString(), Um::IDelete);
10607 	for (int i = 0 ; i < weldList.count(); i++)
10608 	{
10609 		WeldingInfo wInf = weldList.at(i);
10610 		PageItem *item = wInf.weldItem;
10611 		if (item == nullptr)
10612 		{
10613 			qDebug() << "unWeld - null pointer in weldList";
10614 			continue;
10615 		}
10616 		for (int j = 0 ; j < item->weldList.count(); j++)
10617 		{
10618 			WeldingInfo wInf2 = item->weldList.at(j);
10619 			PageItem *item2 = wInf2.weldItem;
10620 			if (item2 == this)
10621 			{
10622 				item->weldList.removeAt(j);
10623 				if (undoManager->undoEnabled())
10624 				{
10625 					ScItemState<PageItem*> *is = new ScItemState<PageItem*>(Um::UnweldItems, QString(), Um::IGroup);
10626 					is->set("UNWELD_ITEM");
10627 					is->setItem(item);
10628 					is->set("thisPoint_x", wInf.weldPoint.x());
10629 					is->set("thisPoint_y", wInf.weldPoint.y());
10630 					is->set("thisID", wInf.weldID);
10631 					is->set("Point_x", wInf2.weldPoint.x());
10632 					is->set("Point_y", wInf2.weldPoint.y());
10633 					is->set("ID", wInf2.weldID);
10634 					undoManager->action(this, is, getUPixmap());
10635 				}
10636 				break;
10637 			}
10638 		}
10639 	}
10640 	if (activeTransaction)
10641 		activeTransaction.commit();
10642 	weldList.clear();
10643 }
10644 
getItemTextSaxed(int selStart,int selLength)10645 QString PageItem::getItemTextSaxed(int selStart, int selLength)
10646 {
10647 	if (selStart < 0 || selLength < 0)
10648 		return QString();
10649 
10650 	StoryText it(m_Doc);
10651 	it.setDefaultStyle(itemText.defaultStyle());
10652 
10653 	if (selLength == 0)
10654 		selLength = 1;
10655 	itemText.deselectAll();
10656 	itemText.select(selStart, selLength);
10657 	it.insert(0, itemText, true);
10658 	itemText.deselectAll();
10659 
10660 	//saxing text
10661 	std::ostringstream xmlString;
10662 	SaxXML xmlStream(xmlString);
10663 	xmlStream.beginDoc();
10664 	it.saxx(xmlStream, "SCRIBUSTEXT");
10665 	xmlStream.endDoc();
10666 	std::string xml(xmlString.str());
10667 	return QString(xml.c_str());
10668 }
10669 
compareItemLevel(const PageItem * item1,const PageItem * item2)10670 bool compareItemLevel(const PageItem* item1, const PageItem* item2)
10671 {
10672 	int level1 = item1->level();
10673 	int level2 = item2->level();
10674 	return (level1 < level2);
10675 }
10676