Rev 24527 |
Rev 24665 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/
/***************************************************************************
pageitem.cpp - description
-------------------
begin : Sat Apr 7 2001
copyright : (C) 2001 by Franz Schmid
email : Franz.Schmid@altmuehlnet.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "pageitem.h"
#include <QDebug>
#include <QFileInfo>
#include <QFont>
#include <QMessageBox>
#include <QPainter>
#include <QPen>
#include <QPoint>
#include <QPointF>
#include <QPolygon>
#include <QRegExp>
#include <QRegion>
#include <QRegularExpression>
#include <cairo.h>
#include <cassert>
#include <qdrawutil.h>
#include <sstream>
#include "appmodes.h"
#include "canvas.h"
#include "canvasmode.h"
#include "cmsettings.h"
#include "colorblind.h"
#include "desaxe/saxXML.h"
#include "iconmanager.h"
#include "marks.h"
#include "pageitem_arc.h"
#include "pageitem_group.h"
#include "pageitem_latexframe.h"
#include "pageitem_line.h"
#include "pageitem_noteframe.h"
#include "pageitem_regularpolygon.h"
#include "pageitem_spiral.h"
#include "pageitem_table.h"
#include "pageitem_textframe.h"
#include "prefsmanager.h"
#include "resourcecollection.h"
#include "scclocale.h"
#include "sccolorengine.h"
#include "scimagecacheproxy.h"
#include "sclimits.h"
#include "scpage.h"
#include "scpainter.h"
#include "scpaths.h"
#include "scpattern.h"
#include "scribusapp.h"
#include "scribuscore.h"
#include "scribusdoc.h"
#include "scribusview.h"
#include "scribuswin.h"
#include "sctextstream.h"
#include "selection.h"
#include "text/storytext.h"
#include "ui/contentpalette.h"
#include "ui/guidemanager.h"
#include "ui/propertiespalette.h"
#include "undomanager.h"
#include "undostate.h"
#include "units.h"
#include "util.h"
#include "util_file.h"
#include "util_formats.h"
#include "util_math.h"
#include "util_text.h"
using namespace std;
PageItem::PageItem(const PageItem & other)
: QObject(other.parent()),
UndoObject(other),
SingleObservable<PageItem>(other.m_Doc->itemsChanged()),
TextContext(this),
// 200 attributes! That is madness, or to quote some famous people from Kriquet:
// "THAT ALL HAS TO GO!"
gXpos(other.gXpos),
gYpos(other.gYpos),
gWidth(other.gWidth),
gHeight(other.gHeight),
GrType(other.GrType),
GrStartX(other.GrStartX),
GrStartY(other.GrStartY),
GrEndX(other.GrEndX),
GrEndY(other.GrEndY),
GrFocalX(other.GrFocalX),
GrFocalY(other.GrFocalY),
GrScale(other.GrScale),
GrSkew(other.GrSkew),
GrExtend(other.GrExtend),
GrControl1(other.GrControl1),
GrControl2(other.GrControl2),
GrControl3(other.GrControl3),
GrControl4(other.GrControl4),
GrControl5(other.GrControl5),
GrColorP1(other.GrColorP1),
GrColorP2(other.GrColorP2),
GrColorP3(other.GrColorP3),
GrColorP4(other.GrColorP4),
GrCol1transp(other.GrCol1transp),
GrCol2transp(other.GrCol2transp),
GrCol3transp(other.GrCol3transp),
GrCol4transp(other.GrCol4transp),
GrCol1Shade(other.GrCol1Shade),
GrCol2Shade(other.GrCol2Shade),
GrCol3Shade(other.GrCol3Shade),
GrCol4Shade(other.GrCol4Shade),
meshGradientPatches(other.meshGradientPatches),
meshGradientArray(other.meshGradientArray),
selectedMeshPointX(other.selectedMeshPointX),
selectedMeshPointY(other.selectedMeshPointY),
selectedMeshControlPoint(other.selectedMeshControlPoint),
snapToPatchGrid(other.snapToPatchGrid),
m_columns(other.m_columns),
m_columnGap(other.m_columnGap),
PLineArt(other.PLineArt),
PLineEnd(other.PLineEnd),
PLineJoin(other.PLineJoin),
NamedLStyle(other.NamedLStyle),
Clip(other.Clip),
PoLine(other.PoLine),
ContourLine(other.ContourLine),
imageClip(other.imageClip),
Segments(other.Segments),
effectsInUse(other.effectsInUse),
PoShow(other.PoShow),
BaseOffs(other.BaseOffs),
textPathType(other.textPathType),
textPathFlipped(other.textPathFlipped),
ClipEdited(other.ClipEdited),
FrameType(other.FrameType),
OwnPage(other.OwnPage),
oldOwnPage(other.oldOwnPage),
pixm(other.pixm),
Pfile(other.Pfile),
Pfile2(other.Pfile2),
Pfile3(other.Pfile3),
ImageProfile(other.ImageProfile),
UseEmbedded(other.UseEmbedded),
EmbeddedProfile(other.EmbeddedProfile),
ImageIntent(other.ImageIntent),
OverrideCompressionMethod(other.OverrideCompressionMethod),
CompressionMethodIndex(other.CompressionMethodIndex),
OverrideCompressionQuality(other.OverrideCompressionQuality),
CompressionQualityIndex(other.CompressionQualityIndex),
imageIsAvailable(other.imageIsAvailable),
OrigW(other.OrigW),
OrigH(other.OrigH),
BBoxX(other.BBoxX),
BBoxH(other.BBoxH),
CurX(other.CurX),
CurY(other.CurY),
itemText(other.itemText),
textLayout(&itemText, this),
isBookmark(other.isBookmark),
HasSel(other.HasSel),
isAutoText(other.isAutoText),
inPdfArticle(other.inPdfArticle),
isRaster(other.isRaster),
OldB(other.OldB),
OldH(other.OldH),
OldB2(other.OldB2),
OldH2(other.OldH2),
Sizing(other.Sizing),
m_layerID(other.m_layerID),
ScaleType(other.ScaleType),
AspectRatio(other.AspectRatio),
DashValues(other.DashValues),
DashOffset(other.DashOffset),
fill_gradient(other.fill_gradient),
fillRule(other.fillRule),
doOverprint(other.doOverprint),
m_leftLink(other.m_leftLink),
m_rightLink(other.m_rightLink),
m_topLink(other.m_topLink),
m_bottomLink(other.m_bottomLink),
LeftLinkID(other.LeftLinkID),
RightLinkID(other.RightLinkID),
TopLinkID(other.TopLinkID),
BottomLinkID(other.BottomLinkID),
LeftLine(other.LeftLine),
RightLine(other.RightLine),
TopLine(other.TopLine),
BottomLine(other.BottomLine),
isTableItem(other.isTableItem),
isSingleSel(other.isSingleSel),
groupItemList(other.groupItemList),
groupWidth(other.groupWidth),
groupHeight(other.groupHeight),
BoundingX(other.BoundingX),
BoundingY(other.BoundingY),
BoundingW(other.BoundingW),
BoundingH(other.BoundingH),
ChangedMasterItem(other.ChangedMasterItem),
OnMasterPage(other.OnMasterPage),
isEmbedded(other.isEmbedded),
m_roundedCornerRadius(other.m_roundedCornerRadius),
oldXpos(other.oldXpos),
oldYpos(other.oldYpos),
oldWidth(other.oldWidth),
oldHeight(other.oldHeight),
oldRot(other.oldRot),
oldLocalScX(other.oldLocalScX),
oldLocalScY(other.oldLocalScY),
oldLocalX(other.oldLocalX),
oldLocalY(other.oldLocalY),
m_Doc(other.m_Doc),
m_lineWidth(other.m_lineWidth),
m_oldLineWidth(other.m_oldLineWidth),
patternStrokeVal(other.patternStrokeVal),
patternStrokeScaleX(other.patternStrokeScaleX),
patternStrokeScaleY(other.patternStrokeScaleY),
patternStrokeOffsetX(other.patternStrokeOffsetX),
patternStrokeOffsetY(other.patternStrokeOffsetY),
patternStrokeRotation(other.patternStrokeRotation),
patternStrokeSkewX(other.patternStrokeSkewX),
patternStrokeSkewY(other.patternStrokeSkewY),
patternStrokeSpace(other.patternStrokeSpace),
patternStrokeMirrorX(other.patternStrokeMirrorX),
patternStrokeMirrorY(other.patternStrokeMirrorY),
patternStrokePath(other.patternStrokePath),
gradientStrokeVal(other.gradientStrokeVal),
stroke_gradient(other.stroke_gradient),
GrTypeStroke(other.GrTypeStroke),
GrStrokeStartX(other.GrStrokeStartX),
GrStrokeStartY(other.GrStrokeStartY),
GrStrokeEndX(other.GrStrokeEndX),
GrStrokeEndY(other.GrStrokeEndY),
GrStrokeFocalX(other.GrStrokeFocalX),
GrStrokeFocalY(other.GrStrokeFocalY),
GrStrokeScale(other.GrStrokeScale),
GrStrokeSkew(other.GrStrokeSkew),
GrMask(other.GrMask),
GrMaskStartX(other.GrMaskStartX),
GrMaskStartY(other.GrMaskStartY),
GrMaskEndX(other.GrMaskEndX),
GrMaskEndY(other.GrMaskEndY),
GrMaskFocalX(other.GrMaskFocalX),
GrMaskFocalY(other.GrMaskFocalY),
GrMaskScale(other.GrMaskScale),
GrMaskSkew(other.GrMaskSkew),
patternMaskScaleX(other.patternMaskScaleX),
patternMaskScaleY(other.patternMaskScaleY),
patternMaskOffsetX(other.patternMaskOffsetX),
patternMaskOffsetY(other.patternMaskOffsetY),
patternMaskRotation(other.patternMaskRotation),
patternMaskSkewX(other.patternMaskSkewX),
patternMaskSkewY(other.patternMaskSkewY),
patternMaskMirrorX(other.patternMaskMirrorX),
patternMaskMirrorY(other.patternMaskMirrorY),
patternMaskVal(other.patternMaskVal),
mask_gradient(other.mask_gradient),
hatchAngle(other.hatchAngle),
hatchDistance(other.hatchDistance),
hatchType(other.hatchType),
hatchUseBackground(other.hatchUseBackground),
hatchBackground(other.hatchBackground),
hatchForeground(other.hatchForeground),
hatchBackgroundQ(other.hatchBackgroundQ),
hatchForegroundQ(other.hatchForegroundQ),
// protected
undoManager(other.undoManager),
firstChar(0), // since this box is unlinked now
m_maxChars(0), // since the layout is invalid now
m_sampleItem(false),
m_textDistanceMargins(other.m_textDistanceMargins),
verticalAlign(other.verticalAlign),
m_itemType(other.m_itemType),
m_itemName(other.m_itemName),
m_isAnnotation(other.m_isAnnotation),
m_annotation(other.m_annotation),
m_gradientName(other.m_gradientName),
m_patternName(other.m_patternName),
patternScaleX(other.patternScaleX),
patternScaleY(other.patternScaleY),
patternOffsetX(other.patternOffsetX),
patternOffsetY(other.patternOffsetY),
patternRotation(other.patternRotation),
patternSkewX(other.patternSkewX),
patternSkewY(other.patternSkewY),
patternMirrorX(other.patternMirrorX),
patternMirrorY(other.patternMirrorY),
m_fillColor(other.m_fillColor),
m_lineColor(other.m_lineColor),
m_lineShade(other.m_lineShade),
m_fillShade(other.m_fillShade),
m_fillTransparency(other.m_fillTransparency),
m_lineTransparency(other.m_lineTransparency),
m_fillBlendMode(other.m_fillBlendMode),
m_lineBlendMode(other.m_lineBlendMode),
m_ImageIsFlippedH(other.m_ImageIsFlippedH),
m_ImageIsFlippedV(other.m_ImageIsFlippedV),
m_Locked(other.m_Locked),
m_SizeLocked(other.m_SizeLocked),
m_SizeHLocked(other.m_SizeHLocked),
m_SizeVLocked(other.m_SizeVLocked),
m_textFlowMode(other.m_textFlowMode),
pageItemAttributes(other.pageItemAttributes),
m_PrintEnabled(other.m_PrintEnabled),
m_fillQColor(other.m_fillQColor),
m_strokeQColor(other.m_strokeQColor),
m_grQColorP1(other.m_grQColorP1),
m_grQColorP2(other.m_grQColorP2),
m_grQColorP3(other.m_grQColorP3),
m_grQColorP4(other.m_grQColorP4),
m_xPos(other.m_xPos),
m_yPos(other.m_yPos),
m_width(other.m_width),
m_height(other.m_height),
m_rotation(other.m_rotation),
m_isSelected(other.m_isSelected),
m_imageVisible(other.m_imageVisible),
m_imageXScale(other.m_imageXScale),
m_imageYScale(other.m_imageYScale),
m_imageXOffset(other.m_imageXOffset),
m_imageYOffset(other.m_imageYOffset),
m_imageRotation(other.m_imageRotation),
m_firstLineOffset(other.m_firstLineOffset),
m_groupClips(other.m_groupClips),
m_startArrowIndex(other.m_startArrowIndex),
m_endArrowIndex(other.m_endArrowIndex),
m_startArrowScale(other.m_startArrowScale),
m_endArrowScale(other.m_endArrowScale),
m_hasSoftShadow(other.m_hasSoftShadow),
m_softShadowColor(other.m_softShadowColor),
m_softShadowShade(other.m_softShadowShade),
m_softShadowBlurRadius(other.m_softShadowBlurRadius),
m_softShadowXOffset(other.m_softShadowXOffset),
m_softShadowYOffset(other.m_softShadowYOffset),
m_softShadowOpacity(other.m_softShadowOpacity),
m_softShadowBlendMode(other.m_softShadowBlendMode),
m_softShadowErasedByObject(other.m_softShadowErasedByObject),
m_softShadowHasObjectTransparency(other.m_softShadowHasObjectTransparency)
{
QString tmp;
m_imageVisible = m_Doc->guidesPrefs().showPic;
m_Doc->TotalItems++;
QString oldName(m_itemName);
int nameNum = m_Doc->TotalItems;
m_itemName += tmp.setNum(m_Doc->TotalItems);
while (m_Doc->itemNameExists(m_itemName))
{
++nameNum;
m_itemName = oldName + tmp.setNum(nameNum);
}
uniqueNr = m_Doc->TotalItems;
invalid = true;
if (other.isInlineImage)
{
QFileInfo inlFi(Pfile);
QString ext = inlFi.suffix();
QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + ext);
tempFile->setAutoRemove(false);
tempFile->open();
QString fileName = getLongPathName(tempFile->fileName());
tempFile->close();
copyFile(Pfile, fileName);
Pfile = fileName;
delete tempFile;
isInlineImage = true;
isTempFile = true;
}
else
{
isInlineImage = false;
isTempFile = false;
}
Parent = nullptr;
unWeld();
}
PageItem::PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
// Initialize superclass(es)
: QObject(doc), SingleObservable<PageItem>(doc->itemsChanged()), TextContext(this),
// Initialize member variables
itemText(doc),
textLayout(&itemText, this),
undoManager(UndoManager::instance())
{
m_Doc = doc;
QString tmp;
gXpos = oldXpos = m_xPos = x;
gYpos = oldYpos = m_yPos = y;
//CB Surely we can remove some of these?
OldB2 = OldB = oldWidth = m_width = w;
OldH2 = OldH = oldHeight = m_height = h;
BoundingX = x;
BoundingY = y;
BoundingW = w;
BoundingH = h;
m_itemType = newType;
m_fillColor = fill;
m_lineColor = m_itemType == PageItem::TextFrame ? fill : outline;
GrEndX = w;
GrControl2 = FPoint(w, 0);
GrControl3 = FPoint(w, h);
GrControl4 = FPoint(0, h);
GrControl5 = FPoint(w / 2.0, h / 2.0);
GrStrokeEndX = w;
m_lineWidth = w2;
m_oldLineWidth = w2;
PLineArt = Qt::PenStyle(m_Doc->itemToolPrefs().shapeLineStyle);
PLineEnd = Qt::FlatCap;
PLineJoin = Qt::MiterJoin;
m_textDistanceMargins = m_Doc->itemToolPrefs().textDistances;
pixm.imgInfo.lowResType = m_Doc->itemToolPrefs().imageLowResType;
switch (m_itemType)
{
case Polygon:
Clip.setPoints(4, static_cast<int>(w / 2), 0, static_cast<int>(w), static_cast<int>(h / 2),
static_cast<int>(w / 2), static_cast<int>(h), 0, static_cast<int>(h / 2));
break;
default:
Clip.setPoints(4, 0, 0, static_cast<int>(w), 0, static_cast<int>(w), static_cast<int>(h), 0, static_cast<int>(h));
break;
}
OwnPage = m_Doc->currentPage() ? m_Doc->currentPage()->pageNr() : -1;
oldOwnPage = OwnPage;
savedOwnPage = OwnPage;
m_imageVisible = m_Doc->guidesPrefs().showPic;
switch (m_itemType)
{
case ImageFrame:
case OSGFrame:
case LatexFrame:
//We can't determine if this is a latex frame here
// because c++'s typeinfos are still saying it's
// a plain pageitem
// This is fixed in the PageItem_LatexFrame constructor
m_itemName = tr("Image");
setUPixmap(Um::IImageFrame);
break;
case TextFrame:
m_itemName = tr("Text");
setUPixmap(Um::ITextFrame);
break;
case Line:
m_itemName = tr("Line");
setUPixmap(Um::ILine);
break;
case Polygon:
m_itemName = tr("Polygon");
setUPixmap(Um::IPolygon);
break;
case PolyLine:
m_itemName = tr("Polyline");
setUPixmap(Um::IPolyline);
break;
case PathText:
m_itemName = tr("PathText");
setUPixmap(Um::IPathText);
break;
case Symbol:
m_itemName = tr("Symbol");
setUPixmap(Um::IPolygon);
break;
case Group:
m_itemName = tr("Group");
setUPixmap(Um::IPolygon);
break;
case RegularPolygon:
m_itemName = tr("RegularPolygon");
setUPixmap(Um::IPolygon);
break;
case Arc:
m_itemName = tr("Arc");
setUPixmap(Um::IPolygon);
break;
case Spiral:
m_itemName = tr("Spiral");
setUPixmap(Um::IPolygon);
break;
case Table:
m_itemName = tr("Table");
//setUPixmap(Um::IPolygon); // TODO: Fix this.
break;
default:
m_itemName = "Item";
break;
}
m_Doc->TotalItems++;
QString oldName(m_itemName);
int nameNum = m_Doc->TotalItems;
m_itemName += tmp.setNum(m_Doc->TotalItems);
while (m_Doc->itemNameExists(m_itemName))
{
++nameNum;
m_itemName = oldName + tmp.setNum(nameNum);
}
uniqueNr = m_Doc->TotalItems;
setUName(m_itemName);
m_annotation.setBorderColor(outline);
// toPixmap = false;
ImageIntent = Intent_Relative_Colorimetric;
m_layerID = m_Doc->activeLayer();
stroke_gradient = VGradient(VGradient::linear);
stroke_gradient.clearStops();
if (m_lineColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_lineColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_lineColor, 100);
stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_lineColor, 100);
}
else
{
if (m_Doc->itemToolPrefs().shapeLineColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeLineColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
}
else
{
if (m_fillColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_fillColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_fillColor, 100);
stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_fillColor, 100);
}
else
{
if (m_Doc->itemToolPrefs().shapeFillColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeFillColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
}
else if (m_Doc->PageColors.contains("Black"))
{
const ScColor& col = m_Doc->PageColors["Black"];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
stroke_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
stroke_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
}
}
}
}
fill_gradient = VGradient(VGradient::linear);
fill_gradient.clearStops();
if (m_fillColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_fillColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_fillColor, 100);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_fillColor, 100);
GrColorP1 = m_fillColor;
GrColorP2 = m_fillColor;
GrColorP3 = m_fillColor;
GrColorP4 = m_fillColor;
}
else
{
if (m_Doc->itemToolPrefs().shapeFillColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeFillColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeFillColor, 100);
GrColorP1 = m_Doc->itemToolPrefs().shapeFillColor;
GrColorP2 = m_Doc->itemToolPrefs().shapeFillColor;
GrColorP3 = m_Doc->itemToolPrefs().shapeFillColor;
GrColorP4 = m_Doc->itemToolPrefs().shapeFillColor;
}
else
{
if (m_lineColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_lineColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_lineColor, 100);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_lineColor, 100);
GrColorP1 = m_lineColor;
GrColorP2 = m_lineColor;
GrColorP3 = m_lineColor;
GrColorP4 = m_lineColor;
}
else
{
if (m_Doc->itemToolPrefs().shapeLineColor != CommonStrings::None)
{
const ScColor& col = m_Doc->PageColors[m_Doc->itemToolPrefs().shapeLineColor];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, m_Doc->itemToolPrefs().shapeLineColor, 100);
GrColorP1 = m_Doc->itemToolPrefs().shapeLineColor;
GrColorP2 = m_Doc->itemToolPrefs().shapeLineColor;
GrColorP3 = m_Doc->itemToolPrefs().shapeLineColor;
GrColorP4 = m_Doc->itemToolPrefs().shapeLineColor;
}
else if (m_Doc->PageColors.contains("Black"))
{
const ScColor& col = m_Doc->PageColors["Black"];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
GrColorP1 = "Black";
GrColorP2 = "Black";
GrColorP3 = "Black";
GrColorP4 = "Black";
}
}
}
}
GrMaskEndX = w;
mask_gradient = VGradient(VGradient::linear);
mask_gradient.clearStops();
const ScColor& col = m_Doc->PageColors["Black"];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
mask_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
mask_gradient.addStop(qcol, 1.0, 0.5, 1.0, "Black", 100);
QList<MeshPoint> mgList;
MeshPoint mgP;
meshGradientPatch patch;
mgP.resetTo(FPoint(0.0, 0.0));
mgP.transparency = 1.0;
mgP.shade = 100;
mgP.colorName = "Black";
mgP.color = qcol;
mgList.append(mgP);
patch.TL = mgP;
mgP.resetTo(FPoint(m_width / 2.0, 0.0));
mgList.append(mgP);
mgP.resetTo(FPoint(m_width, 0.0));
mgList.append(mgP);
patch.TR = mgP;
meshGradientArray.append(mgList);
mgList.clear();
mgP.resetTo(FPoint(0.0, m_height / 2.0));
mgList.append(mgP);
mgP.resetTo(FPoint(m_width / 2.0, m_height / 2.0));
mgList.append(mgP);
mgP.resetTo(FPoint(m_width, m_height / 2.0));
mgList.append(mgP);
meshGradientArray.append(mgList);
mgList.clear();
mgP.resetTo(FPoint(0.0, m_height));
mgList.append(mgP);
patch.BL = mgP;
mgP.resetTo(FPoint(m_width / 2.0, m_height));
mgList.append(mgP);
mgP.resetTo(FPoint(m_width, m_height));
mgList.append(mgP);
patch.BR = mgP;
meshGradientArray.append(mgList);
meshGradientPatches.append(patch);
m_firstLineOffset = m_Doc->itemToolPrefs().firstLineOffset;
m_columns = m_Doc->itemToolPrefs().textColumns;
m_columnGap = m_Doc->itemToolPrefs().textColumnGap;
OnMasterPage = m_Doc->currentPage() ? m_Doc->currentPage()->pageName() : QString();
m_startArrowIndex = m_Doc->itemToolPrefs().lineStartArrow;
m_endArrowIndex = m_Doc->itemToolPrefs().lineEndArrow;
effectsInUse.clear();
//Page Item Attributes
pageItemAttributes.clear();
for (const ObjectAttribute& objAttr : qAsConst(m_Doc->itemAttributes()))
{
if ((objAttr.autoaddto == "textframes" && m_itemType == TextFrame) ||
(objAttr.autoaddto == "imageframes" && m_itemType == ImageFrame))
{
pageItemAttributes.append(objAttr);
}
}
hatchBackground = CommonStrings::None;
hatchBackgroundQ = QColor();
hatchForeground = "Black";
hatchForegroundQ = qcol;
}
PageItem::~PageItem()
{
if ((isTempFile) && (!Pfile.isEmpty()))
QFile::remove(Pfile);
//remove marks
if (isTextFrame())
{
if (!asTextFrame()->isInChain() && itemText.length() > 0)
{
for (int pos = 0; pos < itemText.length(); ++pos)
{
if (itemText.hasMark(pos))
{
Mark* mrk = itemText.mark(pos);
if (!mrk->isType(MARKBullNumType))
m_Doc->eraseMark(mrk);
}
}
}
}
// if (isWeld())
// unWeldFromMaster(true);
// if (isWelded())
// unWeldChild();
}
bool PageItem::isMasterItem() const
{
if (Parent == nullptr)
return !OnMasterPage.isEmpty();
PageItem* parentItem = Parent;
while (parentItem && parentItem->Parent)
parentItem = parentItem->Parent;
return !parentItem->OnMasterPage.isEmpty();
}
bool PageItem::isGroupChild() const
{
return (dynamic_cast<PageItem_Group*>(Parent) != nullptr);
}
bool PageItem::isTableCell() const
{
return (dynamic_cast<PageItem_Table*>(Parent) != nullptr);
}
void PageItem::setXPos(const double newXPos, bool drawingOnly)
{
m_xPos = newXPos;
if (drawingOnly || m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setYPos(const double newYPos, bool drawingOnly)
{
m_yPos = newYPos;
if (drawingOnly || m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setXYPos(const double newXPos, const double newYPos, bool drawingOnly)
{
m_xPos = newXPos;
m_yPos = newYPos;
if (drawingOnly || m_Doc->isLoading())
return;
checkChanges();
}
int PageItem::level() const
{
PageItem* thisItem = const_cast<PageItem*>(this);
if (isGroupChild())
return (Parent->asGroupFrame()->groupItemList.indexOf(thisItem) + 1);
if (!m_Doc)
return 0;
QList<PageItem*>* items = OnMasterPage.isEmpty() ? &m_Doc->DocItems : &m_Doc->MasterItems;
return (items->indexOf(thisItem) + 1);
}
void PageItem::moveBy(const double dX, const double dY, bool drawingOnly)
{
//qDebug() << "pageitem::moveby" << dX << dY;
if (dX==0.0 && dY==0.0)
return;
invalid = true;
if (dX != 0.0)
{
m_xPos += dX;
gXpos += dX;
BoundingX += dX;
}
if (dY != 0.0)
{
m_yPos += dY;
gYpos += dY;
BoundingY += dY;
}
if (drawingOnly || m_Doc->isLoading())
return;
moveWelded(dX, dY);
checkChanges();
}
void PageItem::setWidth(double newWidth)
{
m_width = newWidth;
updateConstants();
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setHeight(double newHeight)
{
m_height = newHeight;
updateConstants();
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setWidthHeight(double newWidth, double newHeight, bool drawingOnly)
{
m_width = newWidth;
m_height = newHeight;
updateConstants();
if (drawingOnly)
return;
checkChanges();
}
void PageItem::setWidthHeight(const double newWidth, const double newHeight)
{
m_width = newWidth;
m_height = newHeight;
updateConstants();
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::resizeBy(const double dH, const double dW)
{
if (dH == 0.0 && dW == 0.0)
return;
if (dH != 0.0)
m_width += dH;
if (dW != 0.0)
m_height += dW;
updateConstants();
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setRotation(const double newRotation, bool drawingOnly)
{
double dR = newRotation - m_rotation;
double oldRot = m_rotation;
m_rotation = newRotation;
while (m_rotation < 0.0)
m_rotation += 360.0;
while (m_rotation > 360.0)
m_rotation -= 360.0;
if (drawingOnly || m_Doc->isLoading())
return;
rotateWelded(dR, oldRot);
checkChanges();
}
void PageItem::rotateBy(const double dR)
{
if (dR==0.0)
return;
m_rotation += dR;
while (m_rotation < 0.0)
m_rotation += 360.0;
while (m_rotation > 360.0)
m_rotation -= 360.0;
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setSelected(const bool toSelect)
{
m_isSelected=toSelect;
}
void PageItem::setImageXScale(const double newImageXScale)
{
m_imageXScale = newImageXScale;
if (m_Doc->isLoading())
{
oldLocalScX = m_imageXScale;
return;
}
checkChanges();
}
void PageItem::setImageYScale(const double newImageYScale)
{
m_imageYScale = newImageYScale;
if (m_Doc->isLoading())
{
oldLocalScY = m_imageYScale;
return;
}
checkChanges();
}
void PageItem::setImageXYScale(const double newImageXScale, const double newImageYScale)
{
m_imageXScale = newImageXScale;
m_imageYScale = newImageYScale;
if (m_Doc->isLoading())
{
oldLocalScX = m_imageXScale;
oldLocalScY = m_imageYScale;
return;
}
checkChanges();
}
void PageItem::setImageXOffset(const double newImageXOffset)
{
m_imageXOffset = newImageXOffset;
if (m_Doc->isLoading())
{
oldLocalX = m_imageXOffset;
return;
}
checkChanges();
}
void PageItem::setImageYOffset(const double newImageYOffset)
{
m_imageYOffset = newImageYOffset;
if (m_Doc->isLoading())
{
oldLocalY = m_imageYOffset;
return;
}
checkChanges();
}
void PageItem::setImageXYOffset(const double newImageXOffset, const double newImageYOffset)
{
m_imageXOffset = newImageXOffset;
m_imageYOffset = newImageYOffset;
if (m_Doc->isLoading())
{
oldLocalX = m_imageXOffset;
oldLocalY = m_imageYOffset;
return;
}
checkChanges();
}
void PageItem::moveImageXYOffsetBy(const double dX, const double dY)
{
if (dX==0.0 && dY==0.0)
return;
if (dX != 0.0)
m_imageXOffset += dX;
if (dY != 0.0)
m_imageYOffset += dY;
if (m_Doc->isLoading())
return;
checkChanges();
}
void PageItem::setImageRotation(const double newRotation)
{
if (m_imageRotation == newRotation)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Rotate, QString(), Um::IRotate);
ss->set("IMAGE_ROTATION");
ss->set("OLD_ROT", m_imageRotation);
ss->set("NEW_ROT", newRotation);
undoManager->action(this, ss);
}
m_imageRotation = newRotation;
if (m_Doc->isLoading())
return;
checkChanges();
}
/// tests if a character is displayed by this frame
bool PageItem::frameDisplays(int textpos) const
{
return 0 <= textpos && textpos < signed(m_maxChars) && textpos < itemText.length();
}
PageItem* PageItem::frameOfChar(int textPos)
{
PageItem* firstFrame = this->firstInChain();
PageItem* nextFrame = firstFrame;
while (nextFrame)
{
if (nextFrame->invalid)
nextFrame->layout();
if (nextFrame->frameDisplays(textPos))
return nextFrame;
nextFrame = nextFrame->nextInChain();
}
return nullptr;
}
//return frame where is text end
PageItem * PageItem::frameTextEnd()
{
PageItem * LastBox = this;
if (frameOverflows() && m_nextBox)
{ // text ending in some next frame
LastBox = m_nextBox;
while (LastBox != nullptr && !LastBox->frameDisplays(itemText.length()-1))
LastBox = LastBox->nextInChain();
}
else if (frameUnderflows() && m_backBox)
{ //text ending in some previous frame
LastBox = m_backBox;
while (LastBox != nullptr && !LastBox->frameDisplays(itemText.length()-1))
LastBox = LastBox->prevInChain();
}
return LastBox;
}
/// returns true if text overflows
bool PageItem::frameOverflows() const
{
// Fix #6991 : "Text overflow" warning when there is a text underflow in fact
/*return NextBox == nullptr && itemText.length() > static_cast<int>(MaxChars);*/
return ( m_nextBox == nullptr )
&& ( firstChar < itemText.length() )
// Fix #7766 : scribus.textOverflows() returns 0 if there is no place for the overflow mark
/*&& ( firstChar < MaxChars )*/
&& ( firstChar <= m_maxChars )
&& ( itemText.length() > m_maxChars );
}
int PageItem::frameOverflowCount() const
{
if (frameOverflows())
return itemText.length()-m_maxChars;
return 0;
}
int PageItem::frameOverflowBlankCount() const
{
if (frameOverflows())
return itemText.plainText().right(itemText.length() - m_maxChars).count(QRegularExpression("\\s+"));
return 0;
}
int PageItem::maxCharsInFrame()
{
return m_maxChars;
}
/// returns true if text is ending before that frame
bool PageItem::frameUnderflows() const
{
if (m_backBox == nullptr)
return false;
//FIX ME - I have found that condition if frame is empty
//and has been linked with previous frame
//if you will find any better solution - fix that function
return (firstInFrame() > lastInFrame());
}
void PageItem::drawOverflowMarker(ScPainter *p)
{
qreal sideLength = 10 / qMax(p->zoomFactor(), 1.0);
qreal offset = 1 / qMax(p->zoomFactor(), 1.0);
qreal left = m_width - sideLength-offset;// / 2;
qreal right = left + sideLength;
qreal top = m_height - sideLength-offset;// * 1.5;
qreal bottom = top + sideLength;
QColor color(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor);
if ((isBookmark) || (m_isAnnotation))
color = PrefsManager::instance().appPrefs.displayPrefs.frameAnnotationColor;
if ((m_backBox != nullptr) || (m_nextBox != nullptr))
color = PrefsManager::instance().appPrefs.displayPrefs.frameLinkColor;
if (m_Locked)
color = PrefsManager::instance().appPrefs.displayPrefs.frameLockColor;
if (m_Doc->m_Selection->containsItem(this))
color = Qt::red;
p->save();
p->setPen(color, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setPenOpacity(1.0);
p->setBrush(Qt::white);
p->setBrushOpacity(1.0);
p->setFillMode(ScPainter::Solid);
p->drawSharpRect(left, top, sideLength, sideLength);
p->drawSharpLine(QPointF(left, top), QPointF(right, bottom));
p->drawSharpLine(QPointF(left, bottom), QPointF(right, top));
p->restore();
}
int PageItem::firstInFrame() const
{
return firstChar;
}
int PageItem::lastInFrame() const
{
return qMin(signed(m_maxChars), itemText.length()) - 1;
}
bool PageItem::canBeLinkedTo(const PageItem* nxt) const
{
if (this->nextInChain() )
return false;
if (!nxt || nxt->prevInChain() )
return false;
for (const PageItem* ff = nxt; ff; ff = ff->nextInChain())
{
if (ff == this)
return false;
}
// If object is placed on a master page, it can be linked only to objects placed on same master page
// Same for objects placed on standard pages : they can only be linked to objects placed on standard pages
return OnMasterPage == nxt->OnMasterPage;
}
void PageItem::link(PageItem* nxt, bool addPARSEP)
{
assert( !nextInChain() );
assert( !nxt->prevInChain() );
for (PageItem* ff=nxt; ff; ff=ff->nextInChain())
{
assert (ff != this);
}
// Append only if necessary to avoid the
// charstyle: access at end of text warning
bool first = false;
bool createUndo = addPARSEP;
if (nxt->prevInChain() == nullptr)
first = true;
int textLen = itemText.length();
if (nxt->itemText.length() > 0)
{ //case when text will be joined with next frame text
//do not add PARSEP if first frame has no text or text ends already with PARSEP
if (addPARSEP && (textLen > 0) && (itemText.text(textLen-1) != SpecialChars::PARSEP))
itemText.insertChars(textLen, SpecialChars::PARSEP);
else
addPARSEP = false;
itemText.append(nxt->itemText);
}
else
addPARSEP = false;
m_nextBox = nxt;
nxt->m_backBox = this;
// update AutoText
if (isAutoText)
{
PageItem* after = nxt;
while (after)
{
after->isAutoText = true;
m_Doc->LastAuto = after;
after = after->m_nextBox;
}
}
else if (nxt->isAutoText)
{
PageItem* before = this;
while (before)
{
before->isAutoText = true;
m_Doc->FirstAuto = before;
before = before->m_backBox;
}
}
invalid = true;
PageItem* prev = this;
while (prev->m_backBox && !prev->m_backBox->frameOverflows())
{
prev->m_backBox->invalid = true;
prev = prev->m_backBox;
}
while (nxt)
{
nxt->itemText = itemText;
nxt->invalid = true;
nxt->firstChar = 0;
nxt = nxt->m_nextBox;
}
if (UndoManager::undoEnabled() && createUndo) //addPARESEP is false only if linking is invoked from undo action for unlinkWithText
{
ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::LinkTextFrame);
is->set("LINK_TEXT_FRAME");
is->set("FIRST", first);
is->set("JOIN_POS", textLen);
is->set("ADDPARSEP", addPARSEP);
is->setItem(qMakePair(this, m_nextBox));
undoManager->action(this, is);
}
}
void PageItem::unlink(bool createUndo)
{
if (m_nextBox)
{
PageItem *undoNextBox=m_nextBox;
// make sure lastInFrame is valid
layout();
/*
//<< CB #6332: Stop the StoryText cut and break and act like other publishing apps
// move following text to new StoryText
itemText.select(lastInFrame()+1, itemText.length()-lastInFrame()-1);
*/
StoryText follow(m_Doc);
/*
follow.setDefaultStyle(itemText.defaultStyle());
follow.insert(0, itemText, true);
// remove following text from this chain
itemText.removeSelection();
//>>
*/
// update auto pointers
if (isAutoText)
{
PageItem* before = this;
while (before)
{
before->isAutoText = false;
before = before->m_backBox;
}
m_Doc->FirstAuto = m_nextBox;
}
// link following frames to new text
m_nextBox->firstChar = 0;
m_nextBox->m_backBox = nullptr;
while (m_nextBox)
{
m_nextBox->itemText = follow;
m_nextBox->invalid = true;
m_nextBox->firstChar = 0;
m_nextBox = m_nextBox->m_nextBox;
}
// NextBox == nullptr now
m_nextBox = nullptr;
if (UndoManager::undoEnabled() && createUndo)
{
ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
is->set("UNLINK_TEXT_FRAME");
is->setItem(qMakePair(this, undoNextBox));
undoManager->action(this, is);
}
}
}
void PageItem::dropLinks()
{
// update auto pointers
if (isAutoText && m_nextBox == nullptr)
m_Doc->LastAuto = m_backBox;
if (isAutoText && m_backBox == nullptr)
m_Doc->FirstAuto = m_nextBox;
isAutoText = false;
// leave text in remaining chain
PageItem* before = m_backBox;
PageItem* after = m_nextBox;
if (after == nullptr && before == nullptr)
return;
itemText = StoryText(m_Doc);
int afterChar = 0;
if (before)
{
before->m_nextBox = after;
afterChar = qMin((int) before->m_maxChars, before->itemText.length());
}
if (after)
{
after->m_backBox = before;
while (after)
{
after->invalid = true;
after->firstChar = afterChar;
after = after->m_nextBox;
}
}
if (UndoManager::undoEnabled())
{
ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
is->set("DROP_LINKS");
is->setItem(qMakePair(m_backBox, m_nextBox));
undoManager->action(this, is);
}
// JG we should set BackBox and NextBox to nullptr at a point
m_backBox = m_nextBox = nullptr;
}
//unlink selected frame from text chain
//but copy or cut its content from itemText
void PageItem::unlinkWithText()
{
PageItem* Next = m_nextBox;
PageItem* Prev = m_backBox;
int length = itemText.length();
if (this->invalid)
layout();
//unlink first frame in chain
if (Prev == nullptr)
{
if (Next->invalid)
Next->layout();
if (lastInFrame() < length -1)
{
StoryText content(m_Doc);
itemText.select(lastInFrame() + 1, length - (lastInFrame() + 1));
content.insert(0, itemText, true);
itemText.removeSelection();
unlink(false);
Next->itemText.insert(0, content);
Next->update();
}
else
{
unlink(false);
}
}
else
{
if (Prev->invalid)
Prev->layout();
itemText.select(firstInFrame(), length - firstInFrame());
StoryText content(m_Doc);
content.insert(0, itemText, true);
itemText.removeSelection();
Prev->unlink(false);
itemText.insert(0, content);
update();
}
if (UndoManager::undoEnabled())
{
ScItemState<QPair<PageItem*, PageItem*> > *is = new ScItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
is->set("UNLINK_TEXT_FRAME");
is->setItem(qMakePair(Prev, Next));
undoManager->action(this, is);
}
}
/// returns the style at the current charpos
const ParagraphStyle& PageItem::currentStyle() const
{
int cursorPosition = itemText.cursorPosition();
if (itemText.hasSelection())
{
int firstSelected = itemText.startOfSelection();
int lastSelected = qMax(itemText.endOfSelection() - 1, 0);
cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
}
// Note: cursor position can be past last characters, don't use frameDisplays() here
if (cursorPosition >= 0 && cursorPosition <= itemText.length())
return itemText.paragraphStyle(cursorPosition);
return itemText.defaultStyle();
}
/// returns the style at the current charpos for changing
ParagraphStyle& PageItem::changeCurrentStyle()
{
int cursorPosition = itemText.cursorPosition();
if (itemText.hasSelection())
{
int firstSelected = itemText.startOfSelection();
int lastSelected = qMax(itemText.endOfSelection() - 1, 0);
cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
}
// Note: cursor position can be past last characters, don't use frameDisplays() here
if (cursorPosition >= 0 && cursorPosition <= itemText.length())
return const_cast<ParagraphStyle&>(itemText.paragraphStyle(cursorPosition));
return const_cast<ParagraphStyle&>(itemText.defaultStyle());
}
/// returns the style at the current charpos
const CharStyle& PageItem::currentCharStyle() const
{
int cursorPosition = itemText.cursorPosition();
if (itemText.hasSelection())
{
int firstSelected = itemText.startOfSelection();
int lastSelected = qMax(itemText.endOfSelection() - 1, 0);
cursorPosition = qMax(firstSelected, qMin(cursorPosition, lastSelected));
}
// Note: cursor position can be past last characters, don't use frameDisplays() here
if (cursorPosition >= 0 && cursorPosition <= itemText.length())
return itemText.charStyle(cursorPosition);
return itemText.defaultStyle().charStyle();
}
void PageItem::currentTextProps(ParagraphStyle& parStyle) const
{
const ParagraphStyle& curStyle = this->currentStyle();
parStyle.setContext(curStyle.context());
parStyle = curStyle;
int position = itemText.cursorPosition();
if (itemText.hasSelection())
position = qMin(qMax(itemText.endOfSelection() - 1, 0), qMax(position, itemText.startOfSelection()));
// Note: cursor position can be past last characters, don't use frameDisplays() here
if (position >= 0 && position <= itemText.length())
{
// Do not use setStyle here otherwise char style properties explicitly
// set at paragraph level without using styles might get lost
parStyle.charStyle().applyCharStyle( itemText.charStyle(position) );
}
else
parStyle.charStyle().setStyle( itemText.defaultStyle().charStyle() );
}
void PageItem::setTextToFrameDistLeft(double newLeft)
{
if (m_textDistanceMargins.left() == newLeft)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
ss->set("LEFT_TEXTFRAMEDIST");
ss->set("OLD_DIST", m_textDistanceMargins.left());
ss->set("NEW_DIST", newLeft);
undoManager->action(this, ss);
}
m_textDistanceMargins.setLeft(newLeft);
//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
}
void PageItem::setTextToFrameDistRight(double newRight)
{
if (m_textDistanceMargins.right() == newRight)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
ss->set("RIGHT_TEXTFRAMEDIST");
ss->set("OLD_DIST", m_textDistanceMargins.right());
ss->set("NEW_DIST", newRight);
undoManager->action(this, ss);
}
m_textDistanceMargins.setRight(newRight);
//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
}
void PageItem::setTextToFrameDistTop(double newTop)
{
if (m_textDistanceMargins.top() == newTop)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
ss->set("TOP_TEXTFRAMEDIST");
ss->set("OLD_DIST", m_textDistanceMargins.top());
ss->set("NEW_DIST", newTop);
undoManager->action(this, ss);
}
m_textDistanceMargins.setTop(newTop);
//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
}
void PageItem::setTextToFrameDistBottom(double newBottom)
{
if (m_textDistanceMargins.bottom() == newBottom)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::TextFrameDist, QString(), Um::ITextFrame);
ss->set("BOTTOM_TEXTFRAMEDIST");
ss->set("OLD_DIST", m_textDistanceMargins.bottom());
ss->set("NEW_DIST", newBottom);
undoManager->action(this, ss);
}
m_textDistanceMargins.setBottom(newBottom);
//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
}
void PageItem::setTextToFrameDist(double newLeft, double newRight, double newTop, double newBottom)
{
UndoTransaction activeTransaction;
if (UndoManager::undoEnabled())
activeTransaction = undoManager->beginTransaction(Um::TextFrame, Um::IDocument, Um::TextFrameDist, QString(), Um::ITextFrame);
setTextToFrameDistLeft(newLeft);
setTextToFrameDistRight(newRight);
setTextToFrameDistTop(newTop);
setTextToFrameDistBottom(newBottom);
if (activeTransaction)
activeTransaction.commit();
//emit textToFrameDistances(Extra, TExtra, BExtra, RExtra);
}
double PageItem::gridOffset() const
{
return m_Doc->guidesPrefs().offsetBaselineGrid;
}
double PageItem::gridDistance() const
{
return m_Doc->guidesPrefs().valueBaselineGrid;
}
void PageItem::setGridOffset(double) { } // FIXME
void PageItem::setGridDistance(double) { } // FIXME
void PageItem::setColumns(int newColumnCount)
{
if (m_columns==newColumnCount)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Columns, QString(), Um::IBorder);
ss->set("COLUMNS");
ss->set("OLD_COLUMNS", m_columns);
ss->set("NEW_COLUMNS", newColumnCount);
undoManager->action(this, ss);
}
m_columns = qMax(1, newColumnCount);
}
void PageItem::setColumnGap(double newColumnGap)
{
if (m_columnGap==newColumnGap)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Columns, QString(), Um::IBorder);
ss->set("COLUMNSGAP");
ss->set("OLD_COLUMNS", m_columnGap);
ss->set("NEW_COLUMNS", newColumnGap);
undoManager->action(this, ss);
}
m_columnGap = newColumnGap;
}
int PageItem::verticalAlignment()
{
return verticalAlign;
}
void PageItem::setVerticalAlignment(int val)
{
if (val == verticalAlign)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::AlignText, QString(), Um::ITextFrame);
ss->set("VERTICAL_ALIGN");
ss->set("OLD_VERTALIGN", verticalAlign);
ss->set("NEW_VERTALIGN", val);
undoManager->action(this, ss);
}
verticalAlign = val;
}
void PageItem::setCornerRadius(double newRadius)
{
if (m_roundedCornerRadius == newRadius)
return;
if (UndoManager::undoEnabled())
{
SimpleState *state = new SimpleState(Um::RoundCorner, QString(), Um::IBorder);
state->set("CORNER_RADIUS");
state->set("OLD_RADIUS", m_roundedCornerRadius);
state->set("NEW_RADIUS", newRadius);
undoManager->action(this,state);
}
m_roundedCornerRadius=newRadius;
//emit cornerRadius(RadRect);
}
/** Paints the item.
CHANGE: cullingArea is in doc coordinates!
*/
void PageItem::DrawObj(ScPainter *p, QRectF cullingArea)
{
// #12698: Prevent drawing of line items
/*if (PoLine.isEmpty())
return;*/
if (cullingArea.isNull())
{
cullingArea = QRectF(QPointF(m_Doc->minCanvasCoordinate.x(), m_Doc->minCanvasCoordinate.y()),
QPointF(m_Doc->maxCanvasCoordinate.x(), m_Doc->maxCanvasCoordinate.y())).toAlignedRect();
}
no_fill = false;
no_stroke = false;
DrawObj_Pre(p);
if (m_Doc->layerOutline(m_layerID))
{
if ((itemType() == TextFrame || itemType() == ImageFrame || itemType() == PathText || itemType() == Line || itemType() == PolyLine || itemType() == Group || itemType() == Symbol))
DrawObj_Item(p, cullingArea);
}
else
{
DrawObj_Item(p, cullingArea);
}
DrawObj_Post(p);
}
void PageItem::DrawObj_Pre(ScPainter *p)
{
p->save();
double lwCorr = m_lineWidth;
double sc = p->zoomFactor();
if ((m_lineWidth * sc) < 1)
lwCorr = 0;
if (!isEmbedded)
p->translate(m_xPos, m_yPos);
p->rotate(m_rotation);
if (m_Doc->layerOutline(m_layerID))
{
p->setPen(m_Doc->layerMarker(m_layerID), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setFillMode(ScPainter::None);
p->setBrushOpacity(1.0);
p->setPenOpacity(1.0);
return;
}
if ((hasSoftShadow()) && (m_Doc->appMode != modeEdit))
DrawSoftShadow(p);
if (isGroup())
return;
p->setBlendModeFill(fillBlendmode());
p->setLineWidth(lwCorr);
if (GrType != 0)
{
if (GrType == Gradient_Pattern)
{
ScPattern *pattern = m_Doc->checkedPattern(m_patternName);
if (!pattern)
{
p->fill_gradient = VGradient(VGradient::linear);
p->fill_gradient.setRepeatMethod(GrExtend);
if (fillColor() != CommonStrings::None)
{
p->setBrush(m_fillQColor);
p->setFillMode(ScPainter::Solid);
}
else
{
no_fill = true;
p->setFillMode(ScPainter::None);
}
if ((!m_patternName.isEmpty()) && (!m_Doc->docPatterns.contains(m_patternName)))
{
GrType = 0;
m_patternName = "";
}
}
else
{
p->setPattern(pattern, patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternMirrorX, patternMirrorY);
p->setFillMode(ScPainter::Pattern);
}
}
else
{
if (GrType == Gradient_4Colors)
{
p->setFillMode(ScPainter::Gradient);
FPoint pG1 = FPoint(0, 0);
FPoint pG2 = FPoint(width(), 0);
FPoint pG3 = FPoint(width(), height());
FPoint pG4 = FPoint(0, height());
p->set4ColorGeometry(pG1, pG2, pG3, pG4, GrControl1, GrControl2, GrControl3, GrControl4);
p->set4ColorColors(m_grQColorP1, m_grQColorP2, m_grQColorP3, m_grQColorP4);
}
else if (GrType == Gradient_Hatch)
{
if (fillColor() != CommonStrings::None)
p->setBrush(m_fillQColor);
p->setFillMode(ScPainter::Hatch);
p->setHatchParameters(hatchType, hatchDistance, hatchAngle, hatchUseBackground, hatchBackgroundQ, hatchForegroundQ, width(), height());
}
else
{
if ((!m_gradientName.isEmpty()) && (!m_Doc->docGradients.contains(m_gradientName)))
m_gradientName = "";
if (!(m_gradientName.isEmpty()) && (m_Doc->docGradients.contains(m_gradientName)))
fill_gradient = m_Doc->docGradients[m_gradientName];
if ((fill_gradient.stops() < 2) && (GrType < Gradient_4Colors)) // fall back to solid filling if there are not enough colorstops in the gradient.
{
if (fillColor() != CommonStrings::None)
{
p->setBrush(m_fillQColor);
p->setFillMode(ScPainter::Solid);
}
else
{
no_fill = true;
p->setFillMode(ScPainter::None);
}
}
else
{
p->setFillMode(ScPainter::Gradient);
p->fill_gradient = fill_gradient;
p->fill_gradient.setRepeatMethod(GrExtend);
switch (GrType)
{
case Gradient_LinearLegacy1:
case Gradient_LinearLegacy2:
case Gradient_LinearLegacy3:
case Gradient_LinearLegacy4:
case Gradient_Linear:
p->setGradient(VGradient::linear, FPoint(GrStartX, GrStartY), FPoint(GrEndX, GrEndY), FPoint(GrStartX, GrStartY), GrScale, GrSkew);
break;
case Gradient_RadialLegacy5:
case Gradient_Radial:
p->setGradient(VGradient::radial, FPoint(GrStartX, GrStartY), FPoint(GrEndX, GrEndY), FPoint(GrFocalX, GrFocalY), GrScale, GrSkew);
break;
case Gradient_Diamond:
p->setFillMode(ScPainter::Gradient);
p->setDiamondGeometry(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), GrControl1, GrControl2, GrControl3, GrControl4, GrControl5);
break;
case Gradient_Mesh:
case Gradient_Conical:
p->setFillMode(ScPainter::Gradient);
p->setMeshGradient(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), meshGradientArray);
break;
case Gradient_PatchMesh:
p->setFillMode(ScPainter::Gradient);
p->setMeshGradient(FPoint(0, 0), FPoint(width(), 0), FPoint(width(), height()), FPoint(0, height()), meshGradientPatches);
break;
}
}
}
}
}
else
{
p->fill_gradient = VGradient(VGradient::linear);
if (fillColor() != CommonStrings::None)
{
p->setBrush(m_fillQColor);
p->setFillMode(ScPainter::Solid);
}
else
{
no_fill = true;
p->setFillMode(ScPainter::None);
}
}
if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0))
{
p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
if (DashValues.count() != 0)
p->setDash(DashValues, DashOffset);
}
else
p->setLineWidth(0);
p->setBrushOpacity(1.0 - fillTransparency());
p->setPenOpacity(1.0 - lineTransparency());
p->setFillRule(fillRule);
if ((GrMask == GradMask_Linear) || (GrMask == GradMask_Radial) || (GrMask == GradMask_LinearLumAlpha) || (GrMask == GradMask_RadialLumAlpha))
{
if ((GrMask == GradMask_Linear) || (GrMask == GradMask_Radial))
p->setMaskMode(1);
else
p->setMaskMode(3);
if ((!gradientMaskVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientMaskVal)))
gradientMaskVal = "";
if (!(gradientMaskVal.isEmpty()) && (m_Doc->docGradients.contains(gradientMaskVal)))
mask_gradient = m_Doc->docGradients[gradientMaskVal];
p->mask_gradient = mask_gradient;
if ((GrMask == GradMask_Linear) || (GrMask == GradMask_LinearLumAlpha))
p->setGradientMask(VGradient::linear, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskStartX, GrMaskStartY), GrMaskScale, GrMaskSkew);
else
p->setGradientMask(VGradient::radial, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskFocalX, GrMaskFocalY), GrMaskScale, GrMaskSkew);
}
else if ((GrMask == GradMask_Pattern) || (GrMask == GradMask_PatternLumAlpha) || (GrMask == GradMask_PatternLumAlphaInverted) || (GrMask == GradMask_PatternInverted))
{
ScPattern *patternMask = m_Doc->checkedPattern(patternMaskVal);
if (patternMask)
{
p->setPatternMask(patternMask, patternMaskScaleX, patternMaskScaleY, patternMaskOffsetX, patternMaskOffsetY, patternMaskRotation, patternMaskSkewX, patternMaskSkewY, patternMaskMirrorX, patternMaskMirrorY);
if (GrMask == GradMask_Pattern)
p->setMaskMode(2);
else if (GrMask == GradMask_PatternLumAlpha)
p->setMaskMode(4);
else if (GrMask == GradMask_PatternLumAlphaInverted)
p->setMaskMode(5);
else
p->setMaskMode(6);
}
else
{
p->setMaskMode(0);
}
}
else
p->setMaskMode(0);
}
void PageItem::DrawObj_Post(ScPainter *p)
{
bool doStroke=true;
double lwCorr = m_lineWidth;
if ((m_lineWidth * p->zoomFactor()) < 1)
lwCorr = 0;
if (m_Doc->layerOutline(m_layerID))
{
if (itemType()!=Line)
{
p->setPen(m_Doc->layerMarker(m_layerID), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setFillMode(ScPainter::None);
p->setBrushOpacity(1.0);
p->setPenOpacity(1.0);
if (itemType() == PolyLine)
p->setupPolygon(&PoLine, false);
else if (itemType() == PathText)
{
if (PoShow)
p->setupPolygon(&PoLine, false);
else
doStroke = false;
}
else
p->setupPolygon(&PoLine);
if (doStroke)
p->strokePath();
if (itemType() == ImageFrame)
{
if (!imageClip.empty())
{
p->setupPolygon(&imageClip);
p->strokePath();
}
}
}
}
else
{
if (!isGroup())
{
p->setBlendModeFill(0);
p->setMaskMode(0);
// TODO: Investigate whether itemType() == Table should really be here. I got artifacts without it so keeping it here for now. /estan
if (itemType() == PathText || itemType() == PolyLine || itemType() == Spiral || itemType() == Line || itemType() == Symbol || itemType() == Group || itemType() == Table)
doStroke=false;
if ((doStroke) && (!m_Doc->RePos))
{
p->setBlendModeStroke(lineBlendmode());
p->setPenOpacity(1.0 - lineTransparency());
if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0))
{
p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
if (DashValues.count() != 0)
p->setDash(DashValues, DashOffset);
}
else
p->setLineWidth(0);
if ((itemType() == LatexFrame) || (itemType() == ImageFrame) || (itemType() == OSGFrame))
p->setupPolygon(&PoLine);
if (NamedLStyle.isEmpty())
{
ScPattern *strokePattern = m_Doc->checkedPattern(patternStrokeVal);
if (strokePattern)
{
if (patternStrokePath)
{
QPainterPath guidePath = PoLine.toQPainterPath(false);
DrawStrokePattern(p, guidePath);
}
else
{
p->setPattern(strokePattern, patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY);
p->setStrokeMode(ScPainter::Pattern);
p->strokePath();
}
}
else if (GrTypeStroke > 0)
{
if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal)))
gradientStrokeVal.clear();
if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal)))
stroke_gradient = m_Doc->docGradients[gradientStrokeVal];
if (stroke_gradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
{
if (lineColor() != CommonStrings::None)
{
p->setBrush(m_strokeQColor);
p->setStrokeMode(ScPainter::Solid);
}
else
{
no_stroke = true;
p->setStrokeMode(ScPainter::None);
}
}
else
{
p->setStrokeMode(ScPainter::Gradient);
p->stroke_gradient = stroke_gradient;
p->stroke_gradient.setRepeatMethod(GrStrokeExtend);
if (GrTypeStroke == Gradient_Linear)
p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew);
else
p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew);
}
p->strokePath();
}
else if (lineColor() != CommonStrings::None)
{
p->setStrokeMode(ScPainter::Solid);
p->setPen(m_strokeQColor, lwCorr, PLineArt, PLineEnd, PLineJoin);
if (DashValues.count() != 0)
p->setDash(DashValues, DashOffset);
p->strokePath();
}
else
no_stroke = true;
if (lineTransparency() > 0.9)
no_stroke = true;
}
else
{
p->setStrokeMode(ScPainter::Solid);
multiLine ml = m_Doc->docLineStyles[NamedLStyle];
QColor tmp;
for (int it = ml.size()-1; it > -1; it--)
{
struct SingleLine& sl = ml[it];
// Qt4 if ((!sl.Color != CommonStrings::None) && (sl.Width != 0))
if (sl.Color != CommonStrings::None) // && (sl.Width != 0))
{
SetQColor(&tmp, sl.Color, sl.Shade);
p->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash), static_cast<Qt::PenCapStyle>(sl.LineEnd), static_cast<Qt::PenJoinStyle>(sl.LineJoin));
p->strokePath();
}
}
}
p->setBlendModeStroke(0);
}
}
}
p->setFillMode(ScPainter::Solid);
p->setBlendModeFill(0);
p->setStrokeMode(ScPainter::Solid);
p->setBlendModeStroke(0);
p->restore();
}
void PageItem::DrawObj_Decoration(ScPainter *p)
{
p->save();
// p->setAntialiasing(false);
if (!isEmbedded)
p->translate(m_xPos, m_yPos);
p->rotate(m_rotation);
if ((!isEmbedded) && (!m_Doc->RePos))
{
double scpInv = 0;
if (!isGroup())
{
if ((drawFrame()) && (m_Doc->guidesPrefs().framesShown) && ((itemType() == ImageFrame) || (itemType() == LatexFrame) || (itemType() == OSGFrame) || (itemType() == PathText)) && (no_stroke))
{
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
if ((isBookmark) || (m_isAnnotation))
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameAnnotationColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
if ((m_backBox != nullptr) || (m_nextBox != nullptr))
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLinkColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
if (m_Locked)
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLockColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setFillMode(ScPainter::None);
if (itemType() == PathText)
{
if (Clip.count() != 0)
{
FPointArray tclip;
FPoint np = FPoint(Clip.point(0));
tclip.resize(2);
tclip.setPoint(0, np);
tclip.setPoint(1, np);
for (int a = 1; a < Clip.size(); ++a)
{
np = FPoint(Clip.point(a));
tclip.putPoints(tclip.size(), 4, np.x(), np.y(), np.x(), np.y(), np.x(), np.y(), np.x(), np.y());
}
np = FPoint(Clip.point(0));
tclip.putPoints(tclip.size(), 2, np.x(), np.y(), np.x(), np.y());
p->setupPolygon(&tclip);
}
}
else
p->setupSharpPolygon(&PoLine);
p->strokePath();
}
}
if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
{
p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
p->setupSharpPolygon(&ContourLine);
p->strokePath();
}
if (itemType() == ImageFrame)
{
double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
double maxres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].maxResolution;
bool checkres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].checkResolution;
if ((((72.0 / imageXScale()) < minres)
|| ((72.0 / imageYScale()) < minres)
|| ((72.0 / imageXScale()) > maxres)
|| ((72.0 / imageYScale()) > maxres))
&& (isRaster) && (checkres) && (!m_Doc->drawAsPreview) && (PrefsManager::instance().appPrefs.displayPrefs.showVerifierWarningsOnCanvas))
{
double ofx = m_width - 22.0;
double ofy = m_height - 22.0;
if ((m_width > 40) && (m_height > 40))
{
p->save();
p->translate(ofx, ofy);
QImage ico = IconManager::instance().loadPixmap("22/dialog-warning.png").toImage();
p->drawImage(&ico);
p->restore();
}
}
}
if ((m_Doc->guidesPrefs().layerMarkersShown) &&
(m_Doc->layerCount() > 1) &&
(!m_Doc->layerOutline(m_layerID)) &&
(!isGroupChild()) &&
(!m_Doc->drawAsPreview))
{
p->setPen(Qt::black, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setPenOpacity(1.0);
p->setBrush(m_Doc->layerMarker(m_layerID));
p->setBrushOpacity(1.0);
p->setFillMode(ScPainter::Solid);
double ofwh = 10;
double ofx = m_width - ofwh/2;
double ofy = m_height - ofwh*3;
p->drawSharpRect(ofx, ofy, ofwh, ofwh);
}
if (no_fill && no_stroke && m_Doc->guidesPrefs().framesShown)
{
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
if (m_Locked)
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameLockColor, scpInv, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->setFillMode(ScPainter::None);
p->drawSharpRect(0, 0, m_width, m_height);
no_fill = false;
no_stroke = false;
}
//CB disabled for now
//if (m_Doc->m_Selection->findItem(this)!=-1)
// drawLockedMarker(p);
}
FrameOnly = false;
// p->setAntialiasing(true);
p->restore();
}
void PageItem::DrawObj_Embedded(ScPainter *p, QRectF cullingArea, const CharStyle& style, PageItem* cembedded)
{
if (!cembedded)
return;
QList<PageItem*> emG;
emG.clear();
emG.append(cembedded);
for (int em = 0; em < emG.count(); ++em)
{
PageItem* embedded = emG.at(em);
p->save();
double x = embedded->xPos();
double y = embedded->yPos();
embedded->m_xPos = embedded->gXpos;
embedded->m_yPos = (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos;
p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
if (style.baselineOffset() != 0)
{
p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
embedded->m_yPos -= embedded->gHeight * (style.baselineOffset() / 1000.0);
}
p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
embedded->invalid = true;
double pws = embedded->m_lineWidth;
embedded->DrawObj_Pre(p);
switch (embedded->itemType())
{
case ImageFrame:
case TextFrame:
case LatexFrame:
case OSGFrame:
case Polygon:
case PathText:
case Symbol:
case Group:
case RegularPolygon:
case Arc:
case Table:
embedded->DrawObj_Item(p, cullingArea);
break;
case Line:
case PolyLine:
case Spiral:
embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
embedded->DrawObj_Item(p, cullingArea);
break;
default:
break;
}
embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
embedded->DrawObj_Post(p);
embedded->m_xPos = x;
embedded->m_yPos = y;
p->restore();
embedded->m_lineWidth = pws;
}
if (m_Doc->guidesPrefs().framesShown)
{
p->save();
p->translate(0, -(cembedded->m_height * (style.scaleV() / 1000.0)));
if (style.baselineOffset() != 0)
p->translate(0, -cembedded->m_height * (style.baselineOffset() / 1000.0));
p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
p->setPen(PrefsManager::instance().appPrefs.displayPrefs.frameNormColor, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
p->setFillMode(ScPainter::None);
p->drawSharpRect(0, 0, cembedded->m_width, cembedded->m_height);
p->restore();
}
}
void PageItem::DrawStrokePattern(ScPainter *p, QPainterPath &path)
{
ScPattern pat = m_Doc->docPatterns[patternStrokeVal];
double pLen = path.length() - ((pat.width / 2.0) * (patternStrokeScaleX / 100.0));
double adv = pat.width * patternStrokeScaleX / 100.0 * patternStrokeSpace;
double xpos = patternStrokeOffsetX * patternStrokeScaleX / 100.0;
while (xpos < pLen)
{
double currPerc = path.percentAtLength(xpos);
double currAngle = path.angleAtPercent(currPerc);
if (currAngle <= 180.0)
currAngle *= -1.0;
else
currAngle = 360.0 - currAngle;
QPointF currPoint = path.pointAtPercent(currPerc);
p->save();
p->translate(currPoint.x(), currPoint.y());
p->rotate(currAngle);
QTransform savWM = p->worldMatrix();
QTransform trans;
trans.translate(0.0, patternStrokeOffsetY);
trans.rotate(patternStrokeRotation);
trans.shear(-patternStrokeSkewX, patternStrokeSkewY);
trans.scale(patternStrokeScaleX / 100.0, patternStrokeScaleY / 100.0);
trans.translate(-pat.width / 2.0, -pat.height / 2.0);
if (patternStrokeMirrorX)
{
trans.translate(pat.width, 0);
trans.scale(-1, 1);
}
if (patternStrokeMirrorY)
{
trans.translate(0, pat.height);
trans.scale(1, -1);
}
trans *= savWM;
p->setWorldMatrix(trans);
for (int em = 0; em < pat.items.count(); ++em)
{
PageItem* embedded = pat.items.at(em);
p->save();
p->translate(embedded->gXpos, embedded->gYpos);
embedded->isEmbedded = true;
embedded->invalid = true;
embedded->DrawObj(p, QRectF());
embedded->isEmbedded = false;
p->restore();
}
p->setWorldMatrix(savWM);
xpos += adv;
p->restore();
}
p->newPath();
}
void PageItem::DrawSoftShadow(ScPainter *p)
{
if (m_softShadowColor == CommonStrings::None)
return;
double lwCorr = m_lineWidth;
double sc = p->zoomFactor();
if ((m_lineWidth * sc) < 1)
lwCorr = 0;
const ScColor& col = m_Doc->PageColors[m_softShadowColor];
QColor tmp = ScColorEngine::getShadeColorProof(col, m_Doc, m_softShadowShade);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
tmp = defect.convertDefect(tmp, m_Doc->previewVisual);
}
p->save();
if (m_softShadowHasObjectTransparency)
p->beginLayer(1.0 - fillTransparency(), m_softShadowBlendMode);
else
p->beginLayer(1.0 - m_softShadowOpacity, m_softShadowBlendMode);
if (!hasFill())
{
double xOffset = isEmbedded ? m_softShadowXOffset : (m_softShadowXOffset - m_xPos);
double yOffset = isEmbedded ? m_softShadowYOffset : (m_softShadowYOffset - m_yPos);
double fillTrans_Old = fillTransparency();
double lineTrans_Old = lineTransparency();
bool hasSoftShadow_Old = hasSoftShadow();
double rotation_Old = m_rotation;
m_fillTransparency = 0.0;
m_lineTransparency = 0.0;
m_rotation = 0;
m_hasSoftShadow = false;
p->save();
p->translate(xOffset, yOffset);
DrawObj(p, QRectF());
p->colorizeAlpha(tmp);
if (m_softShadowBlurRadius > 0)
p->blur(m_softShadowBlurRadius * sc);
p->restore();
if (m_softShadowErasedByObject)
{
p->save();
FPointArray sh = PoLine.copy();
p->beginLayer(1.0, 18, &sh);
p->translate(xOffset - m_softShadowXOffset, yOffset - m_softShadowYOffset);
DrawObj(p, QRectF());
p->endLayer();
p->restore();
}
m_fillTransparency = fillTrans_Old;
m_lineTransparency = lineTrans_Old;
m_hasSoftShadow = hasSoftShadow_Old;
m_rotation = rotation_Old;
}
else
{
FPointArray sh = PoLine.copy();
sh.translate(m_softShadowXOffset, m_softShadowYOffset);
p->setupPolygon(&sh);
p->setBrush(tmp);
p->setFillMode(ScPainter::Solid);
p->fillPath();
if (hasStroke())
{
p->setStrokeMode(ScPainter::Solid);
p->setPen(tmp, lwCorr, PLineArt, PLineEnd, PLineJoin);
p->strokePath();
}
if (m_softShadowBlurRadius > 0)
p->blur(m_softShadowBlurRadius * sc);
if (m_softShadowErasedByObject)
{
sh = PoLine.copy();
p->setupPolygon(&sh);
p->setBrush(tmp);
p->setFillMode(ScPainter::Solid);
p->setBlendModeFill(19);
p->fillPath();
if (hasStroke())
{
p->setBlendModeStroke(19);
p->setStrokeMode(ScPainter::Solid);
p->setPen(tmp, lwCorr, PLineArt, PLineEnd, PLineJoin);
p->strokePath();
}
}
}
p->endLayer();
p->restore();
}
QImage PageItem::DrawObj_toImage(double maxSize, int options)
{
bool isEmbedded_Old = isEmbedded;
double rotation_Old = m_rotation;
double minx = std::numeric_limits<double>::max();
double miny = std::numeric_limits<double>::max();
double maxx = -std::numeric_limits<double>::max();
double maxy = -std::numeric_limits<double>::max();
double x1, x2, y1, y2;
if (options & NoRotation)
m_rotation = 0.0;
getVisualBoundingRect(&x1, &y1, &x2, &y2);
m_rotation = rotation_Old;
double maxAdd = 0;
if (hasSoftShadow() && !(options & NoSoftShadow))
maxAdd = qMax(fabs(softShadowXOffset()), fabs(softShadowYOffset())) + softShadowBlurRadius();
minx = qMin(minx, x1) - maxAdd;
miny = qMin(miny, y1) - maxAdd;
maxx = qMax(maxx, x2) + maxAdd;
maxy = qMax(maxy, y2) + maxAdd;
double igXpos = xPos() - minx;
double igYpos = yPos() - miny;
double igWidth = maxx - minx;
double igHeight = maxy - miny;
double sc = maxSize / qMax(igWidth, igHeight);
bool savedFlag = m_Doc->guidesPrefs().framesShown;
m_Doc->guidesPrefs().framesShown = false;
QImage retImg = QImage(qMax(qRound(igWidth * sc), 1), qMax(qRound(igHeight * sc), 1), QImage::Format_ARGB32_Premultiplied);
retImg.fill( qRgba(0, 0, 0, 0) );
ScPainter *painter = new ScPainter(&retImg, retImg.width(), retImg.height(), 1, 0);
painter->setZoomFactor(sc);
painter->save();
painter->translate(igXpos, igYpos);
if (options & NoRotation)
painter->rotate(-m_rotation);
if (invalid)
layout();
isEmbedded = true;
DrawObj(painter, QRectF());
painter->restore();
painter->end();
delete painter;
m_Doc->guidesPrefs().framesShown = savedFlag;
isEmbedded = isEmbedded_Old;
if ((isEmbedded_Old != isEmbedded) && (isTextFrame() || isPathText()))
{
invalid = true;
layout();
}
return retImg;
}
QImage PageItem::DrawObj_toImage(QList<PageItem*> &emG, double scaling)
{
bool isEmbedded_Old = isEmbedded;
bool savedFlag = m_Doc->guidesPrefs().framesShown;
m_Doc->guidesPrefs().framesShown = false;
QImage retImg = QImage(qRound(gWidth * scaling), qRound(gHeight * scaling), QImage::Format_ARGB32_Premultiplied);
retImg.fill( qRgba(0, 0, 0, 0) );
ScPainter *painter = new ScPainter(&retImg, retImg.width(), retImg.height(), 1, 0);
painter->setZoomFactor(scaling);
for (int em = 0; em < emG.count(); ++em)
{
PageItem* embedded = emG.at(em);
painter->save();
painter->translate(embedded->gXpos, embedded->gYpos);
embedded->isEmbedded = true;
embedded->invalid = true;
embedded->DrawObj(painter, QRectF());
embedded->isEmbedded = false;
painter->restore();
}
painter->end();
delete painter;
m_Doc->guidesPrefs().framesShown = savedFlag;
isEmbedded = isEmbedded_Old;
return retImg;
}
void PageItem::SetQColor(QColor *tmp, const QString& colorName, double shad)
{
if (colorName == CommonStrings::None)
return;
const ScColor& col = m_Doc->PageColors[colorName];
*tmp = ScColorEngine::getShadeColorProof(col, m_Doc, shad);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
*tmp = defect.convertDefect(*tmp, m_Doc->previewVisual);
}
}
void PageItem::DrawPolyL(QPainter *p, const QPolygon& pts)
{
if (Segments.count() == 0)
{
p->drawPolygon(pts);
return;
}
QList<uint>::Iterator it2end = Segments.end();
uint firstVal = 0;
for (QList<uint>::Iterator it2 = Segments.begin(); it2 != it2end; ++it2)
{
p->drawPolygon(pts.constData() + firstVal, (*it2) - firstVal);
firstVal = (*it2);
}
p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
}
void PageItem::setItemName(const QString& newName)
{
if (m_itemName == newName || newName.isEmpty())
return;
QString oldName = m_itemName;
m_itemName = generateUniqueCopyName(newName);
AutoName=false;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Rename, QString(Um::FromTo).arg(oldName, newName));
ss->set("OLD_NAME", oldName);
ss->set("NEW_NAME", newName);
undoManager->action(this, ss);
}
setUName(m_itemName); // set the name for the UndoObject too
}
void PageItem::setGradient(const QString &newGradient)
{
if (m_gradientName == newGradient)
return;
m_gradientName = newGradient;
if (m_Doc->docGradients.contains(m_gradientName))
fill_gradient = m_Doc->docGradients[m_gradientName];
}
void PageItem::setMaskGradient(const VGradient& grad)
{
if (mask_gradient==grad)
return;
if (UndoManager::undoEnabled())
{
ScItemState<QPair<VGradient, VGradient> >* is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
is->set("MASK_GRAD");
is->setItem(qMakePair(mask_gradient, grad));
undoManager->action(this,is);
}
mask_gradient=grad;
}
void PageItem::setFillGradient(const VGradient& grad)
{
if (fill_gradient==grad)
return;
if (UndoManager::undoEnabled())
{
ScItemState<QPair<VGradient,VGradient> > *is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
is->set("FILL_GRAD");
is->setItem(qMakePair(fill_gradient, grad));
undoManager->action(this,is);
}
fill_gradient=grad;
}
void PageItem::setStrokeGradient(const VGradient& grad)
{
if (stroke_gradient==grad)
return;
if (UndoManager::undoEnabled())
{
ScItemState<QPair<VGradient,VGradient> > *is = new ScItemState<QPair<VGradient,VGradient> >(Um::GradVal);
is->set("STROKE_GRAD");
is->setItem(qMakePair(stroke_gradient, grad));
undoManager->action(this,is);
}
stroke_gradient=grad;
}
void PageItem::setPattern(const QString &newPattern)
{
if (m_patternName != newPattern)
m_patternName = newPattern;
}
void PageItem::set4ColorGeometry(FPoint c1, FPoint c2, FPoint c3, FPoint c4)
{
GrControl1 = c1;
GrControl2 = c2;
GrControl3 = c3;
GrControl4 = c4;
}
void PageItem::setDiamondGeometry(const FPoint& c1, const FPoint& c2, const FPoint& c3, const FPoint& c4, const FPoint& c5)
{
GrControl1 = c1;
GrControl2 = c2;
GrControl3 = c3;
GrControl4 = c4;
GrControl5 = c5;
}
void PageItem::set4ColorTransparency(double t1, double t2, double t3, double t4)
{
UndoTransaction trans;
if (UndoManager::undoEnabled())
trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal,QString(), Um::IFill);
setGradientTransp1(t1);
setGradientTransp2(t2);
setGradientTransp3(t3);
setGradientTransp4(t4);
if (trans)
trans.commit();
}
void PageItem::set4ColorShade(int t1, int t2, int t3, int t4)
{
UndoTransaction trans;
if (UndoManager::undoEnabled())
trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal, QString(), Um::IFill);
setGradientShade1(t1);
setGradientShade2(t2);
setGradientShade3(t3);
setGradientShade4(t4);
if (trans)
trans.commit();
}
void PageItem::set4ColorColors(const QString& col1, const QString& col2, const QString& col3, const QString& col4)
{
QColor tmp;
UndoTransaction trans;
if (UndoManager::undoEnabled())
trans = undoManager->beginTransaction(Um::Selection,Um::IFill, Um::GradVal, QString(), Um::IFill);
setGradientCol1(col1);
if (GrColorP1 != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(GrColorP1))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
setGradientCol1(m_Doc->itemToolPrefs().imageFillColor);
break;
case TextFrame:
case PathText:
setGradientCol1(m_Doc->itemToolPrefs().textFillColor);
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
setGradientCol1(m_Doc->itemToolPrefs().shapeFillColor);
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[GrColorP1];
tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol1Shade);
tmp.setAlphaF(GrCol1transp);
setGradientColor1(tmp);
}
else
setGradientColor1(QColor(0, 0, 0, 0));
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
setGradientColor1(defect.convertDefect(m_grQColorP1, m_Doc->previewVisual));
}
setGradientCol2(col2);
if (GrColorP2 != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(GrColorP2))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
setGradientCol2(m_Doc->itemToolPrefs().imageFillColor);
break;
case TextFrame:
case PathText:
setGradientCol2(m_Doc->itemToolPrefs().textFillColor);
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
setGradientCol2(m_Doc->itemToolPrefs().shapeFillColor);
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[GrColorP2];
tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol2Shade);
tmp.setAlphaF(GrCol2transp);
setGradientColor2(tmp);
}
else
setGradientColor2(QColor(0, 0, 0, 0));
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
setGradientColor2(defect.convertDefect(m_grQColorP2, m_Doc->previewVisual));
}
setGradientCol3(col3);
if (GrColorP3 != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(GrColorP3))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
setGradientCol3(m_Doc->itemToolPrefs().imageFillColor);
break;
case TextFrame:
case PathText:
setGradientCol3(m_Doc->itemToolPrefs().textFillColor);
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
setGradientCol3(m_Doc->itemToolPrefs().shapeFillColor);
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[GrColorP3];
tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol3Shade);
tmp.setAlphaF(GrCol3transp);
setGradientColor3(tmp);
}
else
setGradientColor3(QColor(0, 0, 0, 0));
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
setGradientColor3(defect.convertDefect(m_grQColorP3, m_Doc->previewVisual));
}
setGradientCol4(col4);
if (GrColorP4 != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(GrColorP4))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
setGradientCol4(m_Doc->itemToolPrefs().imageFillColor);
break;
case TextFrame:
case PathText:
setGradientCol4(m_Doc->itemToolPrefs().textFillColor);
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
setGradientCol4(m_Doc->itemToolPrefs().shapeFillColor);
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[GrColorP4];
tmp = ScColorEngine::getShadeColorProof(col, m_Doc, GrCol4Shade);
tmp.setAlphaF(GrCol4transp);
setGradientColor4(tmp);
}
else
setGradientColor4(QColor(0, 0, 0, 0));
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
setGradientColor4(defect.convertDefect(m_grQColorP4, m_Doc->previewVisual));
}
if (trans)
trans.commit();
}
void PageItem::get4ColorGeometry(FPoint& c1, FPoint& c2, FPoint& c3, FPoint& c4)
{
c1 = GrControl1;
c2 = GrControl2;
c3 = GrControl3;
c4 = GrControl4;
}
void PageItem::get4ColorTransparency(double &t1, double &t2, double &t3, double &t4)
{
t1 = GrCol1transp;
t2 = GrCol2transp;
t3 = GrCol3transp;
t4 = GrCol4transp;
}
void PageItem::get4ColorColors(QString &col1, QString &col2, QString &col3, QString &col4)
{
col1 = GrColorP1;
col2 = GrColorP2;
col3 = GrColorP3;
col4 = GrColorP4;
}
void PageItem::setMeshPointColor(int x, int y, const QString& color, int shade, double transparency, bool forPatch)
{
QString MColor(color);
QColor MQColor;
if (MColor != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(MColor))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
MColor = m_Doc->itemToolPrefs().imageFillColor;
break;
case TextFrame:
case PathText:
MColor = m_Doc->itemToolPrefs().textFillColor;
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
MColor = m_Doc->itemToolPrefs().shapeFillColor;
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[MColor];
MQColor = ScColorEngine::getShadeColorProof(col, m_Doc, shade);
MQColor.setAlphaF(transparency);
}
else
MQColor = QColor(0, 0, 0, 0);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
MQColor = defect.convertDefect(MQColor, m_Doc->previewVisual);
}
MeshPoint *mp = nullptr;
if (forPatch)
{
meshGradientPatch *patch = &meshGradientPatches[x];
switch (y)
{
case 1:
mp = &(patch->TL);
break;
case 2:
mp = &(patch->TR);
break;
case 3:
mp = &(patch->BR);
break;
case 4:
mp = &(patch->BL);
break;
}
UndoTransaction trans;
if (UndoManager::undoEnabled())
{
trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::GradVal, QString(), Um::IFill);
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",x);
ss->set("Y",y);
ss->set("PATCH",true);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
FPoint xx = mp->gridPoint;
for (int col = 0; col < meshGradientPatches.count(); col++)
{
if (col != x)
{
if (meshGradientPatches[col].TL.gridPoint == xx)
{
mp = &(meshGradientPatches[col].TL);
if (UndoManager::undoEnabled())
{
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",col);
ss->set("Y",1);
ss->set("PATCH",true);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
}
if (meshGradientPatches[col].TR.gridPoint == xx)
{
mp = &(meshGradientPatches[col].TR);
if (UndoManager::undoEnabled())
{
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",col);
ss->set("Y",2);
ss->set("PATCH",true);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
}
if (meshGradientPatches[col].BR.gridPoint == xx)
{
mp = &(meshGradientPatches[col].BR);
if (UndoManager::undoEnabled())
{
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",col);
ss->set("Y",3);
ss->set("PATCH",true);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
}
if (meshGradientPatches[col].BL.gridPoint == xx)
{
mp = &(meshGradientPatches[col].BL);
if (UndoManager::undoEnabled())
{
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",col);
ss->set("Y",4);
ss->set("PATCH",true);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
}
}
}
if (trans)
trans.commit();
}
else
{
if ((x > -1) && (y > -1))
{
mp = &(meshGradientArray[x][y]);
if (UndoManager::undoEnabled())
{
ScItemState<QPair<QColor, QColor> >* ss = new ScItemState<QPair<QColor,QColor> >(Um::GradVal);
ss->set("GRAD_MESH_COLOR");
ss->set("X",x);
ss->set("Y",y);
ss->set("PATCH",false);
ss->set("OLD_COLOR_NAME",mp->colorName);
ss->set("NEW_COLOR_NAME",MColor);
ss->setItem(qMakePair(mp->color,MQColor));
ss->set("OLD_SHADE",mp->shade);
ss->set("NEW_SHADE",shade);
ss->set("OLD_TRANSP",mp->transparency);
ss->set("NEW_TRANSP",transparency);
undoManager->action(this, ss);
}
mp->colorName = MColor;
mp->color = MQColor;
mp->shade = shade;
mp->transparency = transparency;
}
}
}
void PageItem::createGradientMesh(int rows, int cols)
{
QString MColor(m_fillColor);
QColor MQColor;
if (m_fillColor != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(m_fillColor))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
MColor = m_Doc->itemToolPrefs().imageFillColor;
break;
case TextFrame:
case PathText:
MColor = m_Doc->itemToolPrefs().textFillColor;
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
MColor = m_Doc->itemToolPrefs().shapeFillColor;
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[MColor];
MQColor = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
MQColor.setAlphaF(1.0);
}
else
MQColor = QColor(0, 0, 0, 0);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
MQColor = defect.convertDefect(MQColor, m_Doc->previewVisual);
}
if (UndoManager::undoEnabled())
{
ScItemState<QList<QList<MeshPoint> > >* is = new ScItemState<QList<QList<MeshPoint> > >(Um::MeshGradient);
is->set("CREATE_MESH_GRAD");
is->set("ROW",rows);
is->set("COL",cols);
is->setItem(meshGradientArray);
undoManager->action(this,is);
}
meshGradientArray.clear();
if (rows == 0 || cols == 0)
qFatal("PageItem::createGradientMesh: rows or cols is 0");
double xoffs = m_width / static_cast<double>(cols);
double yoffs = m_height / static_cast<double>(rows);
for (int x = 0; x < rows + 1; x++)
{
QList<MeshPoint> mgList;
mgList.reserve(cols + 1);
for (int y = 0; y < cols + 1; y++)
{
MeshPoint mgP;
mgP.resetTo(FPoint(y * xoffs, x * yoffs));
mgP.transparency = 1.0;
mgP.shade = 100;
mgP.colorName = MColor;
mgP.color = MQColor;
mgList.append(mgP);
}
meshGradientArray.append(mgList);
}
}
void PageItem::resetGradientMesh()
{
int rows = meshGradientArray.count();
int cols = meshGradientArray[0].count();
if (UndoManager::undoEnabled())
{
ScItemState<QList<QList<MeshPoint> > > *is = new ScItemState<QList<QList<MeshPoint> > >(Um::ResetControlPoints);
is->set("RESET_MESH_GRAD");
is->setItem(meshGradientArray);
undoManager->action(this,is);
}
double xoffs = m_width / static_cast<double>(cols-1);
double yoffs = m_height / static_cast<double>(rows-1);
for (int x = 0; x < rows; x++)
for (int y = 0; y < cols; y++)
meshGradientArray[x][y].resetTo(FPoint(y * xoffs, x * yoffs));
}
void PageItem::meshToShape()
{
FPointArray Coords;
Coords.resize(0);
Coords.svgInit();
int rows = meshGradientArray.count() - 1;
int cols = meshGradientArray[0].count() - 1;
QList<MeshPoint> mpList;
mpList = meshGradientArray[0];
Coords.svgMoveTo(mpList[0].gridPoint.x(), mpList[0].gridPoint.y());
for (int m = 0; m < mpList.count()-1; m++)
{
Coords.svgCurveToCubic(mpList[m].controlRight.x(), mpList[m].controlRight.y(),
mpList[m+1].controlLeft.x(), mpList[m+1].controlLeft.y(),
mpList[m+1].gridPoint.x(), mpList[m+1].gridPoint.y());
}
for (int m = 0; m < rows; m++)
{
Coords.svgCurveToCubic(meshGradientArray[m][cols].controlBottom.x(), meshGradientArray[m][cols].controlBottom.y(),
meshGradientArray[m+1][cols].controlTop.x(), meshGradientArray[m+1][cols].controlTop.y(),
meshGradientArray[m+1][cols].gridPoint.x(), meshGradientArray[m+1][cols].gridPoint.y());
}
mpList = meshGradientArray[rows];
for (int m = cols; m > 0; m--)
{
Coords.svgCurveToCubic(mpList[m].controlLeft.x(), mpList[m].controlLeft.y(),
mpList[m-1].controlRight.x(), mpList[m-1].controlRight.y(),
mpList[m-1].gridPoint.x(), mpList[m-1].gridPoint.y());
}
for (int m = rows; m > 0; m--)
{
Coords.svgCurveToCubic(meshGradientArray[m][0].controlTop.x(), meshGradientArray[m][0].controlTop.y(),
meshGradientArray[m-1][0].controlBottom.x(), meshGradientArray[m-1][0].controlBottom.y(),
meshGradientArray[m-1][0].gridPoint.x(), meshGradientArray[m-1][0].gridPoint.y());
}
UndoTransaction trans;
if (UndoManager::undoEnabled())
{
trans = undoManager->beginTransaction(Um::Selection, Um::IFill, Um::ChangeMeshGradient, QString(), Um::IFill);
ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> > *ism = new ScItemState<QPair<QList<QList<MeshPoint> >,FPointArray> >(Um::ChangeMeshGradient, QString(), Um::IFill);
ism->set("MOVE_MESH_GRAD");
ism->setItem(qMakePair(meshGradientArray,PoLine));
ism->set("OLDB",OldB2);
ism->set("OLDH",OldH2);
ism->set("FRAME_TYPE",FrameType);
undoManager->action(this, ism);
}
QList<QList<MeshPoint> > meshGradientArrayOld = meshGradientArray;
PoLine = Coords.copy();
double oldX = m_xPos;
double oldY = m_yPos;
ClipEdited = true;
FrameType = 3;
FPoint wh = getMaxClipF(&PoLine);
setWidthHeight(wh.x(),wh.y());
m_Doc->adjustItemSize(this);
OldB2 = width();
OldH2 = height();
updateClip();
meshGradientArray = meshGradientArrayOld;
double dx = oldX - m_xPos;
double dy = oldY - m_yPos;
for (int x = 0; x < rows+1; x++)
for (int y = 0; y < cols+1; y++)
meshGradientArray[x][y].moveRel(dx, dy);
if (UndoManager::undoEnabled())
{
ScItemState<FPointArray> *is = new ScItemState<FPointArray>(Um::ResetContourLine, QString(), Um::IBorder);
is->set("RESET_CONTOUR");
is->setItem(ContourLine);
undoManager->action(this, is);
}
ContourLine = PoLine.copy();
if (trans)
trans.commit();
}
void PageItem::createConicalMesh()
{
VGradient gradient;
gradient.clearStops();
if (fill_gradient.stops() < 2)
{
fill_gradient.clearStops();
const ScColor& col = m_Doc->PageColors["Black"];
QColor qcol = ScColorEngine::getRGBColor(col, m_Doc);
fill_gradient.addStop(qcol, 0.0, 0.5, 1.0, "Black", 100);
const ScColor& col2 = m_Doc->PageColors["White"];
qcol = ScColorEngine::getRGBColor(col2, m_Doc);
fill_gradient.addStop(qcol, 1.0, 0.5, 1.0, "White", 100);
}
QList<VColorStop*> cstops = fill_gradient.colorStops();
double lastStop = -1.0;
double actualStop = 0.0;
bool isFirst = true;
for (int cst = 0; cst < fill_gradient.stops(); ++cst)
{
actualStop = cstops.at(cst)->rampPoint;
if ((actualStop == lastStop) && (!isFirst))
continue;
if (isFirst)
{
if (actualStop != 0.0)
{
gradient.addStop(cstops.at(cst)->color, 0, 0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
if (actualStop <= 0.25)
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);
else
{
double actDist = 0.25;
do
{
gradient.addStop(cstops.at(cst)->color, actDist, actDist, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
actDist += 0.25;
}
while (actualStop > actDist);
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);
}
}
else
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);
isFirst = false;
lastStop = actualStop;
continue;
}
isFirst = false;
if (actualStop - lastStop <= 0.25)
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);
else
{
double actDist = lastStop + 0.25;
do
{
gradient.addStop(computeInBetweenStop(cstops.at(cst-1), cstops.at(cst), actDist));
actDist += 0.25;
}
while (actualStop > actDist);
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);
}
if ((cst == fill_gradient.stops()-1) && (actualStop < 1.0))
{
double distToGo = 1.0 - actualStop;
if (distToGo <= 0.25)
gradient.addStop(cstops.at(cst)->color, 1.0, 1.0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
else
{
do
{
double actDist = actualStop + 0.25;
gradient.addStop(cstops.at(cst)->color, actDist, actDist, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
distToGo -= 0.25;
actDist += 0.25;
}
while (distToGo >= 0.25);
gradient.addStop(cstops.at(cst)->color, 1.0, 1.0, cstops.at(cst)->opacity, cstops.at(cst)->name, cstops.at(cst)->shade);
}
break;
}
lastStop = actualStop;
}
meshGradientArray.clear();
QList<MeshPoint> mgList1;
QList<MeshPoint> mgList2;
MeshPoint mgP1, mgP2, mgP3, mgP4;
QPainterPath path;
FPointArray arcPath;
QLineF angLin = QLineF(QPointF(GrStartX, GrStartY), QPointF(GrEndX, GrEndY));
double startAngle = angLin.angle();
double radius = angLin.length();
double radius2 = radius * 2.0;
QList<VColorStop*> rstops = gradient.colorStops();
if (rstops.count() < 2)
{
const VColorStop* firstStop = rstops.at(0);
if (firstStop->rampPoint > 0)
{
VColorStop* newStop = new VColorStop(*firstStop);
newStop->rampPoint = 0;
rstops.prepend(newStop);
}
if (firstStop->rampPoint < 1.0)
{
VColorStop* newStop = new VColorStop(*firstStop);
newStop->rampPoint = 1.0;
rstops.append(newStop);
}
}
double stepAngle = 360 * rstops.at(1)->rampPoint;
path.arcMoveTo(-radius, -radius, radius2, radius2, 0);
path.arcTo(-radius, -radius, radius2, radius2, 0, -stepAngle);
QTransform mm;
mm.rotate(-startAngle);
path = mm.map(path);
QTransform mr;
mr.scale(1.0, GrScale);
path = mr.map(path);
arcPath.fromQPainterPath(path);
arcPath.translate(GrStartX, GrStartY);
QPointF foc = QPointF(GrFocalX, GrFocalY);
QTransform qmatrix;
qmatrix.translate(GrStartX, GrStartY);
qmatrix.rotate(-startAngle);
qmatrix.translate(0, GrStartY * (1.0 - GrScale));
qmatrix.translate(-GrStartX, -GrStartY);
qmatrix.scale(1, GrScale);
foc = qmatrix.map(foc);
mgP1.resetTo(arcPath.point(0));
mgP1.controlRight = arcPath.point(1);
mgP1.transparency = rstops.at(0)->opacity;
mgP1.shade = rstops.at(0)->shade;
mgP1.colorName = rstops.at(0)->name;
mgP1.color = rstops.at(0)->color;
mgP1.color.setAlphaF(mgP1.transparency);
mgList1.append(mgP1);
mgP2.resetTo(arcPath.point(2));
mgP2.controlLeft = arcPath.point(3);
mgP2.transparency = rstops.at(1)->opacity;
mgP2.shade = rstops.at(1)->shade;
mgP2.colorName = rstops.at(1)->name;
mgP2.color = rstops.at(1)->color;
mgP2.color.setAlphaF(mgP2.transparency);
mgP3.resetTo(FPoint(foc.x(), foc.y()));
mgP3.transparency = rstops.at(0)->opacity;
mgP3.shade = rstops.at(0)->shade;
mgP3.colorName = rstops.at(0)->name;
mgP3.color = rstops.at(0)->color;
mgP3.color.setAlphaF(mgP3.transparency);
mgList2.append(mgP3);
mgP3.transparency = rstops.at(1)->opacity;
mgP3.shade = rstops.at(1)->shade;
mgP3.colorName = rstops.at(1)->name;
mgP3.color = rstops.at(1)->color;
mgP3.color.setAlphaF(mgP3.transparency);
mgList2.append(mgP3);
startAngle -= stepAngle;
for (int rst = 2; rst < gradient.stops(); ++rst)
{
stepAngle = 360 * (rstops.at(rst)->rampPoint - rstops.at(rst-1)->rampPoint);
if (stepAngle <= 0)
continue;
path = QPainterPath();
arcPath.resize(0);
path.arcMoveTo(-radius, -radius, radius2, radius2, 0);
path.arcTo(-radius, -radius, radius2, radius2, 0, -stepAngle);
QTransform mm;
mm.rotate(-startAngle);
QTransform mr;
mr.scale(1.0, GrScale);
path = mm.map(path);
path = mr.map(path);
arcPath.fromQPainterPath(path);
arcPath.translate(GrStartX, GrStartY);
mgP2.controlRight = arcPath.point(1);
mgList1.append(mgP2);
mgP2.resetTo(arcPath.point(2));
mgP2.controlLeft = arcPath.point(3);
mgP2.transparency = rstops.at(rst)->opacity;
mgP2.shade = rstops.at(rst)->shade;
mgP2.colorName = rstops.at(rst)->name;
mgP2.color = rstops.at(rst)->color;
mgP2.color.setAlphaF(mgP2.transparency);
mgP3.transparency = rstops.at(rst)->opacity;
mgP3.shade = rstops.at(rst)->shade;
mgP3.colorName = rstops.at(rst)->name;
mgP3.color = rstops.at(rst)->color;
mgP3.color.setAlphaF(mgP3.transparency);
mgList2.append(mgP3);
startAngle -= stepAngle;
}
mgList1.append(mgP2);
meshGradientArray.append(mgList1);
meshGradientArray.append(mgList2);
}
VColorStop PageItem::computeInBetweenStop(VColorStop* last, VColorStop* actual, double t)
{
double dist = actual->rampPoint - last->rampPoint;
double perc = (t - last->rampPoint) / dist;
double Rn = ((actual->color.redF() - last->color.redF()) * perc) + last->color.redF();
double Gn = ((actual->color.greenF() - last->color.greenF()) * perc) + last->color.greenF();
double Bn = ((actual->color.blueF() - last->color.blueF()) * perc) + last->color.blueF();
QColor color;
color.setRgbF(Rn, Gn, Bn);
double opacity = ((actual->opacity - last->opacity) * perc) + last->opacity;
int shade = qRound(((actual->shade - last->shade) * perc) + last->shade);
QString name = last->name + actual->name + QString("%1").arg(perc);
return VColorStop(t, t, color, opacity, name, shade);
}
void PageItem::gradientVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
{
startX = GrStartX;
startY = GrStartY;
endX = GrEndX;
endY = GrEndY;
focalX = GrFocalX;
focalY = GrFocalY;
scale = GrScale;
skew = GrSkew;
}
void PageItem::setGradientVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
{
GrStartX = startX;
GrStartY = startY;
GrEndX = endX;
GrEndY = endY;
GrFocalX = focalX;
GrFocalY = focalY;
GrScale = scale;
GrSkew = skew;
}
void PageItem::setStrokeGradient(const QString &newGradient)
{
if (gradientStrokeVal != newGradient)
gradientStrokeVal = newGradient;
}
void PageItem::strokeGradientVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
{
startX = GrStrokeStartX;
startY = GrStrokeStartY;
endX = GrStrokeEndX;
endY = GrStrokeEndY;
focalX = GrStrokeFocalX;
focalY = GrStrokeFocalY;
scale = GrStrokeScale;
skew = GrStrokeSkew;
}
void PageItem::setStrokeGradientVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
{
GrStrokeStartX = startX;
GrStrokeStartY = startY;
GrStrokeEndX = endX;
GrStrokeEndY = endY;
GrStrokeFocalX = focalX;
GrStrokeFocalY = focalY;
GrStrokeScale = scale;
GrStrokeSkew = skew;
}
void PageItem::setPatternTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY)
{
patternScaleX = scaleX;
patternScaleY = scaleY;
patternOffsetX = offsetX;
patternOffsetY = offsetY;
patternRotation = rotation;
patternSkewX = skewX;
patternSkewY = skewY;
}
void PageItem::patternTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY) const
{
scaleX = patternScaleX;
scaleY = patternScaleY;
offsetX = patternOffsetX;
offsetY = patternOffsetY;
rotation = patternRotation;
skewX = patternSkewX;
skewY = patternSkewY;
}
void PageItem::setPatternFlip(bool flipX, bool flipY)
{
patternMirrorX = flipX;
patternMirrorY = flipY;
}
void PageItem::patternFlip(bool &flipX, bool &flipY)
{
flipX = patternMirrorX;
flipY = patternMirrorY;
}
void PageItem::setMaskType(int val)
{
if (GrMask == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::GradTypeMask, QString(), Um::IFill);
ss->set("MASKTYPE");
ss->set("NEW", val);
ss->set("OLD", GrMask);
undoManager->action(this, ss);
}
GrMask = val;
}
void PageItem::setGradientMask(const QString &newMask)
{
if (gradientMaskVal != newMask)
gradientMaskVal = newMask;
}
void PageItem::setPatternMask(const QString &newMask)
{
if (patternMaskVal != newMask)
patternMaskVal = newMask;
}
void PageItem::maskVector(double& startX, double& startY, double& endX, double& endY, double &focalX, double &focalY, double &scale, double &skew) const
{
startX = GrMaskStartX;
startY = GrMaskStartY;
endX = GrMaskEndX;
endY = GrMaskEndY;
focalX = GrMaskFocalX;
focalY = GrMaskFocalY;
scale = GrMaskScale;
skew = GrMaskSkew;
}
void PageItem::setMaskVector(double startX, double startY, double endX, double endY, double focalX, double focalY, double scale, double skew)
{
GrMaskStartX = startX;
GrMaskStartY = startY;
GrMaskEndX = endX;
GrMaskEndY = endY;
GrMaskFocalX = focalX;
GrMaskFocalY = focalY;
GrMaskScale = scale;
GrMaskSkew = skew;
}
void PageItem::maskTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY) const
{
scaleX = patternMaskScaleX;
scaleY = patternMaskScaleY;
offsetX = patternMaskOffsetX;
offsetY = patternMaskOffsetY;
rotation = patternMaskRotation;
skewX = patternMaskSkewX;
skewY = patternMaskSkewY;
}
void PageItem::setMaskTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY)
{
patternMaskScaleX = scaleX;
patternMaskScaleY = scaleY;
patternMaskOffsetX = offsetX;
patternMaskOffsetY = offsetY;
patternMaskRotation = rotation;
patternMaskSkewX = skewX;
patternMaskSkewY = skewY;
}
void PageItem::setMaskFlip(bool flipX, bool flipY)
{
patternMaskMirrorX = flipX;
patternMaskMirrorY = flipY;
}
void PageItem::maskFlip(bool &flipX, bool &flipY)
{
flipX = patternMaskMirrorX;
flipY = patternMaskMirrorY;
}
void PageItem::setFillColor(const QString &newColor)
{
QString tmp = newColor;
if (tmp != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(newColor))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
tmp = m_Doc->itemToolPrefs().imageFillColor;
break;
case TextFrame:
case PathText:
tmp = m_Doc->itemToolPrefs().textFillColor;
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
tmp = m_Doc->itemToolPrefs().shapeFillColor;
break;
default:
break;
}
}
}
if (m_fillColor == tmp)
{
setFillQColor();
return;
}
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SetFill,
QString(Um::ColorFromTo).arg(m_fillColor, tmp),
Um::IFill);
ss->set("FILL");
ss->set("OLD_FILL", m_fillColor);
ss->set("NEW_FILL", tmp);
undoManager->action(this, ss);
}
m_fillColor = tmp;
setFillQColor();
}
void PageItem::setFillShade(double newShade)
{
if (m_fillShade == newShade)
{
setFillQColor();
return;
}
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SetShade,
QString(Um::FromTo).arg(m_fillShade).arg(newShade),
Um::IShade);
ss->set("SHADE");
ss->set("OLD_SHADE", m_fillShade);
ss->set("NEW_SHADE", newShade);
undoManager->action(this, ss);
}
m_fillShade = newShade;
setFillQColor();
}
void PageItem::setFillTransparency(double newTransparency)
{
if (m_fillTransparency == newTransparency)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Transparency,
QString(Um::FromTo).arg(m_fillTransparency).arg(newTransparency),
Um::ITransparency);
ss->set("TRANSPARENCY");
ss->set("OLD_TP", m_fillTransparency);
ss->set("NEW_TP", newTransparency);
undoManager->action(this, ss);
}
m_fillTransparency = newTransparency;
}
void PageItem::setFillBlendmode(int newBlendmode)
{
if (m_fillBlendMode == newBlendmode)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::BlendMode, nullptr, Um::IGroup);
ss->set("FILLBLENDMODE", newBlendmode);
ss->set("FILLBLENDMODE_OLD", m_fillBlendMode);
undoManager->action(this, ss);
}
m_fillBlendMode = newBlendmode;
}
void PageItem::setLineColor(const QString &newColor)
{
QString tmp = newColor;
if (tmp != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(newColor))
{
switch (itemType())
{
case TextFrame:
case PathText:
tmp = m_Doc->itemToolPrefs().textLineColor;
break;
case Line:
tmp = m_Doc->itemToolPrefs().lineColor;
break;
case PolyLine:
case Polygon:
case ImageFrame:
case LatexFrame:
case OSGFrame:
case RegularPolygon:
case Arc:
case Spiral:
tmp = m_Doc->itemToolPrefs().shapeLineColor;
break;
default:
break;
}
}
}
if (m_lineColor == tmp)
{
setLineQColor();
return;
}
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SetLineColor,
QString(Um::ColorFromTo).arg(m_lineColor, tmp),
Um::IFill);
ss->set("LINE_COLOR");
ss->set("OLD_COLOR", m_lineColor);
ss->set("NEW_COLOR", tmp);
undoManager->action(this, ss);
}
m_lineColor = tmp;
setLineQColor();
}
void PageItem::setLineShade(double newShade)
{
if (m_lineShade == newShade)
{
setLineQColor();
return;
}
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SetLineShade,
QString(Um::FromTo).arg(m_lineShade).arg(newShade),
Um::IShade);
ss->set("LINE_SHADE");
ss->set("OLD_SHADE", m_lineShade);
ss->set("NEW_SHADE", newShade);
undoManager->action(this, ss);
}
m_lineShade = newShade;
setLineQColor();
}
void PageItem::setStrokePattern(const QString &newPattern)
{
if (patternStrokeVal != newPattern)
patternStrokeVal = newPattern;
}
void PageItem::setStrokePatternToPath(bool enable)
{
patternStrokePath = enable;
}
bool PageItem::isStrokePatternToPath()
{
return patternStrokePath;
}
void PageItem::setStrokePatternTransform(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, double space)
{
patternStrokeScaleX = scaleX;
patternStrokeScaleY = scaleY;
patternStrokeOffsetX = offsetX;
patternStrokeOffsetY = offsetY;
patternStrokeRotation = rotation;
patternStrokeSkewX = skewX;
patternStrokeSkewY = skewY;
patternStrokeSpace = space;
}
void PageItem::setStrokePatternFlip(bool flipX, bool flipY)
{
patternStrokeMirrorX = flipX;
patternStrokeMirrorY = flipY;
}
void PageItem::strokePatternFlip(bool &flipX, bool &flipY)
{
flipX = patternStrokeMirrorX;
flipY = patternStrokeMirrorY;
}
void PageItem::strokePatternTransform(double &scaleX, double &scaleY, double &offsetX, double &offsetY, double &rotation, double &skewX, double &skewY, double &space) const
{
scaleX = patternStrokeScaleX;
scaleY = patternStrokeScaleY;
offsetX = patternStrokeOffsetX;
offsetY = patternStrokeOffsetY;
rotation = patternStrokeRotation;
skewX = patternStrokeSkewX;
skewY = patternStrokeSkewY;
space = patternStrokeSpace;
}
void PageItem::setLineQColor()
{
if (m_lineColor != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(m_lineColor))
{
switch (itemType())
{
case TextFrame:
case PathText:
m_lineColor = m_Doc->itemToolPrefs().textLineColor;
break;
case Line:
m_lineColor = m_Doc->itemToolPrefs().lineColor;
break;
case PolyLine:
case Polygon:
case ImageFrame:
case LatexFrame:
case OSGFrame:
case RegularPolygon:
case Arc:
case Spiral:
m_lineColor = m_Doc->itemToolPrefs().shapeLineColor;
break;
default:
break;
}
}
if (!m_Doc->PageColors.contains(m_lineColor))
m_lineColor = m_Doc->itemToolPrefs().shapeLineColor;
const ScColor& col = m_Doc->PageColors[m_lineColor];
m_strokeQColor = ScColorEngine::getShadeColorProof(col, m_Doc, m_lineShade);
}
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
m_strokeQColor = defect.convertDefect(m_strokeQColor, m_Doc->previewVisual);
}
}
void PageItem::setFillQColor()
{
if (m_fillColor != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(m_fillColor))
{
switch (itemType())
{
case ImageFrame:
case LatexFrame:
case OSGFrame:
m_fillColor = m_Doc->itemToolPrefs().imageFillColor;
break;
case TextFrame:
case PathText:
m_fillColor = m_Doc->itemToolPrefs().textFillColor;
break;
case Line:
case PolyLine:
case Polygon:
case RegularPolygon:
case Arc:
case Spiral:
m_fillColor = m_Doc->itemToolPrefs().shapeFillColor;
break;
default:
break;
}
}
const ScColor& col = m_Doc->PageColors[m_fillColor];
m_fillQColor = ScColorEngine::getShadeColorProof(col, m_Doc, m_fillShade);
}
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
m_fillQColor = defect.convertDefect(m_fillQColor, m_Doc->previewVisual);
}
}
void PageItem::setHatchParameters(int mode, double distance, double angle, bool useBackground, const QString& background, const QString& foreground)
{
hatchType = mode;
hatchDistance = distance;
hatchAngle = angle;
hatchUseBackground = useBackground;
hatchBackground = background;
hatchForeground = foreground;
if (background != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(background))
hatchBackgroundQ = QColor();
else
{
const ScColor& col = m_Doc->PageColors[background];
hatchBackgroundQ = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
hatchBackgroundQ = defect.convertDefect(hatchBackgroundQ, m_Doc->previewVisual);
}
}
}
if (foreground != CommonStrings::None)
{
if (!m_Doc->PageColors.contains(foreground))
hatchForegroundQ = QColor();
else
{
const ScColor& col = m_Doc->PageColors[foreground];
hatchForegroundQ = ScColorEngine::getShadeColorProof(col, m_Doc, 100);
if (m_Doc->viewAsPreview)
{
VisionDefectColor defect;
hatchForegroundQ = defect.convertDefect(hatchForegroundQ, m_Doc->previewVisual);
}
}
}
}
void PageItem::setLineTransparency(double newTransparency)
{
if (m_lineTransparency == newTransparency)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::LineTransparency,
QString(Um::FromTo).arg(m_lineTransparency).arg(newTransparency),
Um::ITransparency);
ss->set("LINE_TRANSPARENCY");
ss->set("OLD_TP", m_lineTransparency);
ss->set("NEW_TP", newTransparency);
undoManager->action(this, ss);
}
m_lineTransparency = newTransparency;
}
void PageItem::setLineBlendmode(int newBlendmode)
{
if (m_lineBlendMode == newBlendmode)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::BlendMode, nullptr, Um::IGroup);
ss->set("LINEBLENDMODE", newBlendmode);
ss->set("LINEBLENDMODE_OLD", m_lineBlendMode);
undoManager->action(this, ss);
}
m_lineBlendMode = newBlendmode;
}
void PageItem::setLineStyle(Qt::PenStyle newStyle)
{
if (PLineArt == newStyle)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::LineStyle, QString(), Um::ILineStyle);
ss->set("LINE_STYLE");
ss->set("OLD_STYLE", static_cast<int>(PLineArt));
ss->set("NEW_STYLE", static_cast<int>(newStyle));
undoManager->action(this, ss);
}
PLineArt = newStyle;
}
void PageItem::setLineWidth(double newWidth)
{
if ((m_lineWidth == newWidth) || (isGroup()))
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::LineWidth,
QString(Um::FromTo).arg(m_lineWidth).arg(newWidth),Um::ILineStyle);
ss->set("LINE_WIDTH");
ss->set("OLD_LINEWIDTH", m_lineWidth);
ss->set("NEW_LINEWIDTH", newWidth);
undoManager->action(this, ss);
}
m_oldLineWidth=m_lineWidth;
m_lineWidth = newWidth;
}
void PageItem::setLineEnd(Qt::PenCapStyle newStyle)
{
if (PLineEnd == newStyle)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::LineEnd, QString(), Um::ILineStyle);
ss->set("LINE_END");
ss->set("OLD_STYLE", static_cast<int>(PLineEnd));
ss->set("NEW_STYLE", static_cast<int>(newStyle));
undoManager->action(this, ss);
}
PLineEnd = newStyle;
}
void PageItem::setLineJoin(Qt::PenJoinStyle newStyle)
{
if (PLineJoin == newStyle)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::LineJoin, QString(), Um::ILineStyle);
ss->set("LINE_JOIN");
ss->set("OLD_STYLE", static_cast<int>(PLineJoin));
ss->set("NEW_STYLE", static_cast<int>(newStyle));
undoManager->action(this, ss);
}
PLineJoin = newStyle;
}
void PageItem::setCustomLineStyle(const QString& newStyle)
{
if (NamedLStyle == newStyle)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
QString oldStyle = NamedLStyle.isEmpty() ? Um::NoStyle : NamedLStyle;
QString nStyle = newStyle.isEmpty() ? Um::NoStyle : newStyle;
QString action = newStyle.isEmpty() ? Um::NoLineStyle : Um::CustomLineStyle;
SimpleState *ss = new SimpleState(action, QString(Um::FromTo).arg(oldStyle, nStyle), Um::ILineStyle);
ss->set("CUSTOM_LINE_STYLE");
ss->set("OLD_STYLE", NamedLStyle);
ss->set("NEW_STYLE", newStyle);
undoManager->action(this, ss);
}
NamedLStyle = newStyle;
}
void PageItem::setStartArrowIndex(int newIndex)
{
if (m_startArrowIndex == newIndex)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::StartArrow, QString(), Um::IArrow);
ss->set("START_ARROW");
ss->set("OLD_INDEX", m_startArrowIndex);
ss->set("NEW_INDEX", newIndex);
undoManager->action(this, ss);
}
m_startArrowIndex = newIndex;
}
void PageItem::setEndArrowIndex(int newIndex)
{
if (m_endArrowIndex == newIndex)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::EndArrow, QString(), Um::IArrow);
ss->set("END_ARROW");
ss->set("OLD_INDEX", m_endArrowIndex);
ss->set("NEW_INDEX", newIndex);
undoManager->action(this, ss);
}
m_endArrowIndex = newIndex;
}
void PageItem::setStartArrowScale(int newScale)
{
if (m_startArrowScale == newScale)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::StartArrowScale, QString(), Um::IArrow);
ss->set("START_ARROWSCALE");
ss->set("OLD_SCALE", m_startArrowScale);
ss->set("NEW_SCALE", newScale);
undoManager->action(this, ss);
}
m_startArrowScale = newScale;
}
void PageItem::setEndArrowScale(int newScale)
{
if (m_endArrowScale == newScale)
return; // nothing to do -> return
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::EndArrowScale, QString(), Um::IArrow);
ss->set("END_ARROWSCALE");
ss->set("OLD_SCALE", m_endArrowScale);
ss->set("NEW_SCALE", newScale);
undoManager->action(this, ss);
}
m_endArrowScale = newScale;
}
void PageItem::setImageFlippedH(bool flipped)
{
if (flipped != m_ImageIsFlippedH)
flipImageH();
}
void PageItem::flipImageH()
{
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::FlipH, nullptr, Um::IFlipH);
ss->set("IMAGEFLIPH");
undoManager->action(this, ss);
}
m_ImageIsFlippedH = !m_ImageIsFlippedH;
}
void PageItem::setImageFlippedV(bool flipped)
{
if (flipped != m_ImageIsFlippedV)
flipImageV();
}
void PageItem::flipImageV()
{
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::FlipV, nullptr, Um::IFlipV);
ss->set("IMAGEFLIPV");
undoManager->action(this, ss);
}
m_ImageIsFlippedV = !m_ImageIsFlippedV;
}
void PageItem::setImageScalingMode(bool freeScale, bool keepRatio)
{
if (ScaleType == freeScale && AspectRatio == keepRatio)
return;
if (UndoManager::undoEnabled())
{
QString from = ScaleType ? Um::FreeScaling : Um::FrameSize;
from += ", ";
from += AspectRatio ? Um::KeepRatio : Um::BreakRatio;
QString to = freeScale ? Um::FreeScaling : Um::FrameSize;
to += ", ";
to += keepRatio ? Um::KeepRatio : Um::BreakRatio;
SimpleState *ss = new SimpleState(Um::ImageScaling, QString(Um::FromTo).arg(from, to), Um::IImageScaling);
ss->set("SCALE_MODE");
if (freeScale != ScaleType)
{
ss->set("SCALE_TYPE", freeScale);
if (!freeScale)
{
//if switching from free scaling to frame size
//in undo must be offset and scale saved
ss->set("OLD_IMAGEXOFFSET", m_imageXOffset);
ss->set("OLD_IMAGEYOFFSET", m_imageYOffset);
ss->set("OLD_IMAGEXSCALE", m_imageXScale);
ss->set("OLD_IMAGEYSCALE", m_imageYScale);
}
}
if (keepRatio != AspectRatio)
ss->set("ASPECT_RATIO", keepRatio);
undoManager->action(this, ss);
}
ScaleType = freeScale;
AspectRatio = keepRatio;
adjustPictScale();
update();
}
void PageItem::setOverprint(bool val)
{
if (doOverprint == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::Overprint, nullptr, Um::IGroup);
ss->set("OVERPRINT", val);
undoManager->action(this, ss);
}
doOverprint = val;
}
void PageItem::setHasSoftShadow(bool val)
{
if (m_hasSoftShadow == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SoftShadow, nullptr, Um::IGroup);
ss->set("SOFT_SHADOW");
ss->set("NEW_VALUE", val);
ss->set("OLD_VALUE", m_hasSoftShadow);
undoManager->action(this, ss);
}
m_hasSoftShadow = val;
}
void PageItem::setSoftShadowColor(const QString &val)
{
if (m_softShadowColor == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SoftShadowColor, nullptr, Um::IGroup);
ss->set("SOFT_SHADOW_COLOR");
ss->set("NEW_VALUE", val);
ss->set("OLD_VALUE", m_softShadowColor);
undoManager->action(this, ss);
}
m_softShadowColor = val;
}
void PageItem::setSoftShadowShade(int val)
{
if (m_softShadowShade == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SoftShadowShade, nullptr, Um::IGroup);
ss->set("SOFT_SHADOW_SHADE");
ss->set("NEW_VALUE", val);
ss->set("OLD_VALUE", m_softShadowShade);
undoManager->action(this, ss);
}
m_softShadowShade = val;
}
void PageItem::setSoftShadowBlurRadius(double val)
{
if (m_softShadowBlurRadius == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SoftShadowBlurRadius, nullptr, Um::IGroup);
ss->set("SOFT_SHADOW_BLUR_RADIUS");
ss->set("NEW_VALUE", val);
ss->set("OLD_VALUE", m_softShadowBlurRadius);
undoManager->action(this, ss);
}
m_softShadowBlurRadius = val;
}
void PageItem::setSoftShadowXOffset(double val)
{
if (m_softShadowXOffset == val)
return;
if (UndoManager::undoEnabled())
{
SimpleState *ss = new SimpleState(Um::SoftShadowXOffset, nullptr, Um::IGroup);
ss->set("SOFT_SHADOW_XOFFSET");
ss->set("NEW_VALUE", val);
ss->set("OLD_VALUE", m_softShadowXOffset);
undoManager->action(<