Compare commits

..

7 Commits

Author SHA1 Message Date
thomas_lucky13 c584393a60 merge new_images 2 years ago
thomas_lucky13 c6ca99f84b Draw dashed and dotted lines 2 years ago
Clément Fauconnier d4b91d8d34 changed version to 1.6.3 3 years ago
Clément Fauconnier cb6271802e changed build version to 0613 3 years ago
kaamui db5f03fe28
Merge pull request #629 from letsfindaway/628-bug-ruler 3 years ago
letsfindaway 29861cab73 fix: handling of active ruler 3 years ago
letsfindaway f1ea20c9dc fix: ruler stays effective after deleted from board 3 years ago
  1. 4
      OpenBoard.pro
  2. 3
      resources/OpenBoard.qrc
  3. 48
      resources/forms/mainWindow.ui
  4. 126
      resources/images/toolbar/dashedLine.svg
  5. 145
      resources/images/toolbar/dottedLine.svg
  6. 126
      resources/images/toolbar/solidLine.svg
  7. 108
      src/adaptors/UBCFFSubsetAdaptor.cpp
  8. 1
      src/adaptors/UBCFFSubsetAdaptor.h
  9. 239
      src/adaptors/UBSvgSubsetAdaptor.cpp
  10. 4
      src/adaptors/UBSvgSubsetAdaptor.h
  11. 64
      src/board/UBBoardController.cpp
  12. 9
      src/board/UBBoardController.h
  13. 6
      src/board/UBBoardView.cpp
  14. 24
      src/board/UBDrawingController.cpp
  15. 5
      src/board/UBDrawingController.h
  16. 11
      src/core/UB.h
  17. 35
      src/core/UBSettings.cpp
  18. 6
      src/core/UBSettings.h
  19. 191
      src/domain/UBGraphicsLineItem.cpp
  20. 100
      src/domain/UBGraphicsLineItem.h
  21. 148
      src/domain/UBGraphicsScene.cpp
  22. 5
      src/domain/UBGraphicsScene.h
  23. 3
      src/domain/UBItem.cpp
  24. 2
      src/domain/domain.pri
  25. 6
      src/tools/UBGraphicsRuler.cpp
  26. 4
      src/tools/UBGraphicsTriangle.cpp

@ -9,9 +9,9 @@ CONFIG += debug_and_release \
VERSION_MAJ = 1 VERSION_MAJ = 1
VERSION_MIN = 6 VERSION_MIN = 6
VERSION_PATCH = 2 VERSION_PATCH = 3
VERSION_TYPE = r # a = alpha, b = beta, rc = release candidate, r = release, other => error VERSION_TYPE = r # a = alpha, b = beta, rc = release candidate, r = release, other => error
VERSION_BUILD = 0502 VERSION_BUILD = 0613
VERSION = "$${VERSION_MAJ}.$${VERSION_MIN}.$${VERSION_PATCH}-$${VERSION_TYPE}.$${VERSION_BUILD}" VERSION = "$${VERSION_MAJ}.$${VERSION_MIN}.$${VERSION_PATCH}-$${VERSION_TYPE}.$${VERSION_BUILD}"

@ -126,6 +126,9 @@
<file>images/toolbar/eraserTool.png</file> <file>images/toolbar/eraserTool.png</file>
<file>images/toolbar/lineTool.png</file> <file>images/toolbar/lineTool.png</file>
<file>images/toolbar/tools.png</file> <file>images/toolbar/tools.png</file>
<file>images/toolbar/solidLine.svg</file>
<file>images/toolbar/dashedLine.svg</file>
<file>images/toolbar/dottedLine.svg</file>
<file>images/stylusPalette/arrow.png</file> <file>images/stylusPalette/arrow.png</file>
<file>images/stylusPalette/arrowOn.png</file> <file>images/stylusPalette/arrowOn.png</file>
<file>images/stylusPalette/handPlay.png</file> <file>images/stylusPalette/handPlay.png</file>

@ -1702,6 +1702,54 @@
<string>Draw intermediate grid lines</string> <string>Draw intermediate grid lines</string>
</property> </property>
</action> </action>
<action name="actionLineSolid">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../OpenBoard.qrc">
<normaloff>:/images/toolbar/solidLine.svg</normaloff>:/images/toolbar/solidLine.svg</iconset>
</property>
<property name="text">
<string>Line Style</string>
</property>
<property name="toolTip">
<string>Solid Style</string>
</property>
</action>
<action name="actionLineDashed">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../OpenBoard.qrc">
<normaloff>:/images/toolbar/dashedLine.svg</normaloff>:/images/toolbar/dashedLine.svg</iconset>
</property>
<property name="text">
<string>Line Style</string>
</property>
<property name="toolTip">
<string>Dashed Style</string>
</property>
</action>
<action name="actionLineDotted">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../OpenBoard.qrc">
<normaloff>:/images/toolbar/dottedLine.svg</normaloff>:/images/toolbar/dottedLine.svg</iconset>
</property>
<property name="text">
<string>Line Style</string>
</property>
<property name="toolTip">
<string>Dotted Style</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="../OpenBoard.qrc"/> <include location="../OpenBoard.qrc"/>

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="42"
height="42"
viewBox="0 0 42 42"
version="1.1"
id="svg38508"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="dashedLine.svg"
inkscape:export-filename="/home/dmitry/git/OpenBoard/resources/images/stylusPalette/arrow_svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview38510"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:zoom="11.313708"
inkscape:cx="18.870913"
inkscape:cy="20.903845"
inkscape:window-width="1920"
inkscape:window-height="1003"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g965"
inkscape:document-rotation="0"
inkscape:snap-others="true"
inkscape:snap-global="false"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid7387"
dotted="false" />
</sodipodi:namedview>
<defs
id="defs38505">
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5-3"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2-7" />
</filter>
</defs>
<g
inkscape:label="icon"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-152.84748,-194.2822)">
<g
id="g965"
inkscape:label="line">
<path
style="fill:none;stroke:#000000;stroke-width:3.6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:10.8,10.8;stroke-dashoffset:0;stroke-opacity:1"
d="m 154.68586,234.52153 38.80777,-38.81827"
id="path963"
sodipodi:nodetypes="cc" />
</g>
</g>
<metadata
id="metadata854">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:export-filename="/home/dmitry/git/OpenBoard/resources/images/stylusPalette/arrow_svg.png"
sodipodi:docname="dottedLine.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
id="svg38508"
version="1.1"
viewBox="0 0 42 42"
height="42"
width="42"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview38510"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:zoom="7.9999996"
inkscape:cx="41.437502"
inkscape:cy="-10.0625"
inkscape:window-width="1920"
inkscape:window-height="1003"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g965"
inkscape:document-rotation="0"
inkscape:snap-others="true"
inkscape:snap-global="false"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid7387"
dotted="false" />
</sodipodi:namedview>
<defs
id="defs38505">
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5-3"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2-7" />
</filter>
</defs>
<g
inkscape:label="icon"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-152.84748,-194.2822)">
<g
id="g965"
inkscape:label="line">
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.53588;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.878431;paint-order:stroke fill markers"
id="circle2549"
cx="157.40373"
cy="231.92728"
r="3.4577076" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.53588;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.878431;paint-order:stroke fill markers"
id="circle2587"
cx="168.27238"
cy="221.2583"
r="3.4577076" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.53588;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.878431;paint-order:stroke fill markers"
id="circle2589"
cx="179.28416"
cy="210.2368"
r="3.4577076" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.53588;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.878431;paint-order:stroke fill markers"
id="circle2591"
cx="190.15662"
cy="199.18091"
r="3.4577076" />
</g>
</g>
<metadata
id="metadata854">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="42"
height="42"
viewBox="0 0 42 42"
version="1.1"
id="svg38508"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="solidLine.svg"
inkscape:export-filename="/home/dmitry/git/OpenBoard/resources/images/stylusPalette/arrow_svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview38510"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:zoom="11.313708"
inkscape:cx="18.870913"
inkscape:cy="20.903845"
inkscape:window-width="1920"
inkscape:window-height="1003"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g965"
inkscape:document-rotation="0"
inkscape:snap-others="true"
inkscape:snap-global="false"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050">
<inkscape:grid
type="xygrid"
id="grid7387"
dotted="false" />
</sodipodi:namedview>
<defs
id="defs38505">
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter37990-9-5-3"
inkscape:label="shadowFilter"
x="-0.067811772"
y="-0.07751945"
width="1.1356235"
height="1.1873387">
<feGaussianBlur
stdDeviation="0.29999999999999999"
id="feGaussianBlur37992-3-6-6" />
<feOffset
dx="0"
dy="0.29999999999999999"
id="feOffset37994-2-2-7" />
</filter>
</defs>
<g
inkscape:label="icon"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-152.84748,-194.2822)">
<g
id="g965"
inkscape:label="line">
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 155.10847,234.22611 192.7862,196.30525"
id="path963"
sodipodi:nodetypes="cc" />
</g>
</g>
<metadata
id="metadata854">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -38,6 +38,7 @@
#include "domain/UBItem.h" #include "domain/UBItem.h"
#include "domain/UBGraphicsPolygonItem.h" #include "domain/UBGraphicsPolygonItem.h"
#include "domain/UBGraphicsLineItem.h"
#include "domain/UBGraphicsStroke.h" #include "domain/UBGraphicsStroke.h"
#include "domain/UBGraphicsTextItem.h" #include "domain/UBGraphicsTextItem.h"
#include "domain/UBGraphicsSvgItem.h" #include "domain/UBGraphicsSvgItem.h"
@ -74,6 +75,7 @@ static QString tG = "g";
static QString tSwitch = "switch"; static QString tSwitch = "switch";
static QString tPolygon = "polygon"; static QString tPolygon = "polygon";
static QString tPolyline = "polyline"; static QString tPolyline = "polyline";
static QString tLine = "line";
static QString tRect = "rect"; static QString tRect = "rect";
static QString tSvg = "svg"; static QString tSvg = "svg";
static QString tText = "text"; static QString tText = "text";
@ -90,6 +92,8 @@ static QString aFill = "fill";
static QString aFillopacity = "fill-opacity"; static QString aFillopacity = "fill-opacity";
static QString aX = "x"; static QString aX = "x";
static QString aY = "y"; static QString aY = "y";
static QString aX2 = "x2";
static QString aY2 = "y2";
static QString aWidth = "width"; static QString aWidth = "width";
static QString aHeight = "height"; static QString aHeight = "height";
static QString aStroke = "stroke"; static QString aStroke = "stroke";
@ -115,6 +119,7 @@ static QString aHref = "href";
static QString aBackground = "background"; static QString aBackground = "background";
static QString aLocked = "locked"; static QString aLocked = "locked";
static QString aEditable = "editable"; static QString aEditable = "editable";
static QString aLinestyle = "line-style";
//attributes part names //attributes part names
static QString apRotate = "rotate"; static QString apRotate = "rotate";
@ -581,6 +586,108 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement &
return true; return true;
} }
bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgLine(const QDomElement &element)
{
QString svgPoints = element.attribute(aPoints);
QLineF line;
qreal x1 = element.attribute(aX).toDouble();
qreal y1 = element.attribute(aY).toDouble();
qreal x2 = element.attribute(aX2).toDouble();
qreal y2 = element.attribute(aY2).toDouble();
qreal width = element.attribute(aWidth).toDouble();
qreal height = element.attribute(aHeight).toDouble();
QString textStrokeColor = element.attribute(aStroke);
QString textStrokeWidth = element.attribute(aStrokewidth);
qreal style = element.attribute(aLinestyle).toDouble();
QColor strokeColor = !textStrokeColor.isNull() ? colorFromString(textStrokeColor) : QColor();
int strokeWidth = textStrokeWidth.toInt();
width += strokeWidth;
height += strokeWidth;
QPen pen;
if (strokeColor.isValid()) {
pen.setColor(strokeColor);
}
if (strokeWidth)
pen.setWidth(strokeWidth);
if (style == 2)
{
pen.setStyle(Qt::PenStyle::DotLine);
pen.setCapStyle(Qt::PenCapStyle::RoundCap);
} else if (style == 1)
{
pen.setStyle(Qt::PenStyle::DashLine);
} else
{
pen.setStyle(Qt::PenStyle::SolidLine);
}
QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length()));
QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1));
if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ
{
UBGraphicsLineItem *graphicsLine = new UBGraphicsLineItem(line);
UBGraphicsStroke *stroke = new UBGraphicsStroke();
//graphicsLine->setStroke(stroke);
graphicsLine->setPen(pen);
QTransform transform;
QString textTransform = element.attribute(aTransform);
graphicsLine->resetTransform();
if (!textTransform.isNull()) {
transform = transformFromString(textTransform, graphicsLine);
}
mCurrentScene->addItem(graphicsLine);
graphicsLine->setUuid(itemUuid);
mRefToUuidMap.insert(element.attribute(aId), itemUuid.toString());
}
else // simple CFF
{
QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width());
QPainter painter;
painter.begin(generator);
painter.setPen(pen);
painter.drawLine(x1, y1, x2, y2);
painter.end();
//add resulting svg file to scene
UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName()));
QString uuid = QUuid::createUuid().toString();
mRefToUuidMap.insert(element.attribute(aId), uuid);
svgItem->setUuid(QUuid(uuid));
QTransform transform;
QString textTransform = element.attribute(aTransform);
svgItem->resetTransform();
if (!textTransform.isNull()) {
transform = transformFromString(textTransform, svgItem);
}
repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform);
hashSceneItem(element, svgItem);
if (mGSectionContainer)
{
addItemToGSection(svgItem);
}
delete generator;
}
return true;
}
void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(const QDomElement &element, void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(const QDomElement &element,
qreal &fontSize, QColor &fontColor, QString &fontFamily, qreal &fontSize, QColor &fontColor, QString &fontFamily,
QString &fontStretch, bool &italic, int &fontWeight, QString &fontStretch, bool &italic, int &fontWeight,
@ -1101,6 +1208,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgElement(const QDomElement &p
else if (tagName == tEllipse && !parseSvgEllipse(parent)) return false; else if (tagName == tEllipse && !parseSvgEllipse(parent)) return false;
else if (tagName == tPolygon && !parseSvgPolygon(parent)) return false; else if (tagName == tPolygon && !parseSvgPolygon(parent)) return false;
else if (tagName == tPolyline && !parseSvgPolyline(parent)) return false; else if (tagName == tPolyline && !parseSvgPolyline(parent)) return false;
else if (tagName == tLine && !parseSvgLine(parent)) return false;
else if (tagName == tText && !parseSvgText(parent)) return false; else if (tagName == tText && !parseSvgText(parent)) return false;
else if (tagName == tTextarea && !parseSvgTextarea(parent)) return false; else if (tagName == tTextarea && !parseSvgTextarea(parent)) return false;
else if (tagName == tImage && !parseSvgImage(parent)) return false; else if (tagName == tImage && !parseSvgImage(parent)) return false;

@ -110,6 +110,7 @@ private:
inline bool parseSvgEllipse(const QDomElement &element); inline bool parseSvgEllipse(const QDomElement &element);
inline bool parseSvgPolygon(const QDomElement &element); inline bool parseSvgPolygon(const QDomElement &element);
inline bool parseSvgPolyline(const QDomElement &element); inline bool parseSvgPolyline(const QDomElement &element);
inline bool parseSvgLine(const QDomElement &element);
inline bool parseSvgText(const QDomElement &element); inline bool parseSvgText(const QDomElement &element);
inline bool parseSvgTextarea(const QDomElement &element); inline bool parseSvgTextarea(const QDomElement &element);
inline bool parseSvgImage(const QDomElement &element); inline bool parseSvgImage(const QDomElement &element);

@ -40,6 +40,7 @@
#include "domain/UBGraphicsPixmapItem.h" #include "domain/UBGraphicsPixmapItem.h"
#include "domain/UBGraphicsProxyWidget.h" #include "domain/UBGraphicsProxyWidget.h"
#include "domain/UBGraphicsPolygonItem.h" #include "domain/UBGraphicsPolygonItem.h"
#include "domain/UBGraphicsLineItem.h"
#include "domain/UBGraphicsMediaItem.h" #include "domain/UBGraphicsMediaItem.h"
#include "domain/UBGraphicsWidgetItem.h" #include "domain/UBGraphicsWidgetItem.h"
#include "domain/UBGraphicsPDFItem.h" #include "domain/UBGraphicsPDFItem.h"
@ -618,6 +619,46 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
group->addToGroup(polygonItem); group->addToGroup(polygonItem);
} }
} }
else if (mXmlReader.name() == "lineL")
{
UBGraphicsLineItem* lineItem = 0;
QString parentId = mXmlReader.attributes().value(mNamespaceUri, "parent").toString();
lineItem = lineItemFromLineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black);
if(parentId.isEmpty() && strokesGroup)
parentId = strokesGroup->uuid().toString();
if(parentId.isEmpty())
parentId = QUuid::createUuid().toString();
if (lineItem)
{
lineItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic));
UBGraphicsStrokesGroup* group;
if(!mStrokesList.contains(parentId)){
group = new UBGraphicsStrokesGroup();
mStrokesList.insert(parentId,group);
group->setTransform(lineItem->transform());
UBGraphicsItem::assignZValue(group, lineItem->zValue());
}
else
group = mStrokesList.value(parentId);
if (!currentStroke)
currentStroke = new UBGraphicsStroke();
if(lineItem->transform().isIdentity())
lineItem->setTransform(group->transform());
group->addToGroup(lineItem);
lineItem->show();
group->addToGroup(lineItem);
}
}
else if (mXmlReader.name() == "polyline") else if (mXmlReader.name() == "polyline")
{ {
QList<UBGraphicsPolygonItem*> polygonItems = polygonItemsFromPolylineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); QList<UBGraphicsPolygonItem*> polygonItems = polygonItemsFromPolylineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black);
@ -1300,6 +1341,49 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy,
continue; continue;
} }
// Is the item a line?
UBGraphicsLineItem *lineItem = qgraphicsitem_cast<UBGraphicsLineItem*> (item);
if (lineItem && lineItem->isVisible())
{
mXmlWriter.writeStartElement("g");
QColor colorOnDarkBackground = lineItem->colorOnDarkBackground();
QColor colorOnLightBackground = lineItem->colorOnLightBackground();
if (colorOnDarkBackground.isValid() && colorOnLightBackground.isValid() && lineItem)
{
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value"
, QString("%1").arg(lineItem->zValue()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri
, "fill-on-dark-background", colorOnDarkBackground.name());
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri
, "fill-on-light-background", colorOnLightBackground.name());
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(lineItem->uuid()));
QVariant locked = lineItem->data(UBGraphicsItemData::ItemLocked);
if (!locked.isNull() && locked.toBool())
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "locked", xmlTrue);
QVariant layer = lineItem->data(UBGraphicsItemData::ItemLayerType);
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "layer", QString("%1").arg(layer.toInt()));
QMatrix matrix = lineItem->sceneMatrix();
if (!matrix.isIdentity())
mXmlWriter.writeAttribute("transform", toSvgTransform(matrix));
qDebug() << "Attributes written";
groupHoldsInfo = true;
}
lineItemToSvgLine(lineItem, groupHoldsInfo);
continue;
}
if (openStroke) if (openStroke)
{ {
mXmlWriter.writeEndElement(); //g mXmlWriter.writeEndElement(); //g
@ -1555,6 +1639,53 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgLine(UBGraphicsPolyg
} }
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::lineItemToSvgLine(UBGraphicsLineItem* lineItem, bool groupHoldsInfo)
{
mXmlWriter.writeStartElement("lineL");
QLineF line = lineItem->originalLine();
mXmlWriter.writeAttribute("x1", QString::number(line.p1().x(), 'f', 2));
mXmlWriter.writeAttribute("y1", QString::number(line.p1().y(), 'f', 2));
// SVG renderers (Chrome) do not like line where (x1, y1) == (x2, y2)
qreal x2 = line.p2().x();
if (line.p1() == line.p2())
x2 += 0.01;
mXmlWriter.writeAttribute("x2", QString::number(x2, 'f', 2));
mXmlWriter.writeAttribute("y2", QString::number(line.p2().y(), 'f', 2));
mXmlWriter.writeAttribute("stroke-width", QString::number(lineItem->originalWidth(), 'f', -1));
mXmlWriter.writeAttribute("stroke", lineItem->pen().color().name());
qreal alpha = lineItem->pen().color().alphaF();
if (alpha < 1.0)
mXmlWriter.writeAttribute("stroke-opacity", QString::number(alpha, 'f', 2));
mXmlWriter.writeAttribute("stroke-linecap", "round");
switch (lineItem->style())
{
case Qt::PenStyle::DotLine:
mXmlWriter.writeAttribute("line-style", "2");
break;
case Qt::PenStyle::DashLine:
mXmlWriter.writeAttribute("line-style", "1");
break;
default:
mXmlWriter.writeAttribute("line-style", "0");
}
if (!groupHoldsInfo)
{
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value", QString("%1").arg(lineItem->zValue()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-dark-background", lineItem->colorOnDarkBackground().name());
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-light-background", lineItem->colorOnLightBackground().name());
}
mXmlWriter.writeEndElement();
}
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo) void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo)
{ {
@ -1901,6 +2032,114 @@ UBGraphicsPolygonItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemFromLin
return polygonItem; return polygonItem;
} }
UBGraphicsLineItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::lineItemFromLineSvg(const QColor& pDefaultColor)
{
QStringRef svgX1 = mXmlReader.attributes().value("x1");
QStringRef svgY1 = mXmlReader.attributes().value("y1");
QStringRef svgX2 = mXmlReader.attributes().value("x2");
QStringRef svgY2 = mXmlReader.attributes().value("y2");
qreal style = mXmlReader.attributes().value("line-style").toDouble();
QLineF line;
if (!svgX1.isNull() && !svgY1.isNull() && !svgX2.isNull() && !svgY2.isNull())
{
qreal x1 = svgX1.toString().toFloat();
qreal y1 = svgY1.toString().toFloat();
qreal x2 = svgX2.toString().toFloat();
qreal y2 = svgY2.toString().toFloat();
line.setLine(x1, y1, x2, y2);
}
else
{
qWarning() << "cannot make sense of 'line' value";
return 0;
}
QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width");
qreal lineWidth = 1.;
if (!strokeWidth.isNull())
{
lineWidth = strokeWidth.toString().toFloat();
}
UBGraphicsLineItem* lineItem = new UBGraphicsLineItem(line, lineWidth);
graphicsItemFromSvg(lineItem);
QStringRef svgStroke = mXmlReader.attributes().value("stroke");
QColor penColor = pDefaultColor;
if (!svgStroke.isNull())
{
penColor.setNamedColor(svgStroke.toString());
}
QStringRef svgStrokeOpacity = mXmlReader.attributes().value("stroke-opacity");
qreal opacity = 1.0;
if (!svgStrokeOpacity.isNull())
{
opacity = svgStrokeOpacity.toString().toFloat();
penColor.setAlphaF(opacity);
}
lineItem->setColor(penColor);
if (style == 2)
{
lineItem->setStyle(Qt::PenStyle::DotLine);
} else if (style == 1)
{
lineItem->setStyle(Qt::PenStyle::DashLine);
} else
{
lineItem->setStyle(Qt::PenStyle::SolidLine);
}
QStringRef ubFillOnDarkBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-dark-background");
if (!ubFillOnDarkBackground.isNull())
{
QColor color;
color.setNamedColor(ubFillOnDarkBackground.toString());
if (!color.isValid())
color = Qt::white;
color.setAlphaF(opacity);
lineItem->setColorOnDarkBackground(color);
}
else
{
QColor color = mGroupDarkBackgroundColor;
color.setAlphaF(opacity);
lineItem->setColorOnDarkBackground(color);
}
QStringRef ubFillOnLightBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-light-background");
if (!ubFillOnLightBackground.isNull())
{
QColor color;
color.setNamedColor(ubFillOnLightBackground.toString());
if (!color.isValid())
color = Qt::black;
color.setAlphaF(opacity);
lineItem->setColorOnLightBackground(color);
}
else
{
QColor color = mGroupLightBackgroundColor;
color.setAlphaF(opacity);
lineItem->setColorOnLightBackground(color);
}
return lineItem;
}
QList<UBGraphicsPolygonItem*> UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemsFromPolylineSvg(const QColor& pDefaultColor) QList<UBGraphicsPolygonItem*> UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemsFromPolylineSvg(const QColor& pDefaultColor)
{ {
QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width"); QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width");

@ -38,6 +38,7 @@
class UBGraphicsSvgItem; class UBGraphicsSvgItem;
class UBGraphicsPolygonItem; class UBGraphicsPolygonItem;
class UBGraphicsLineItem;
class UBGraphicsPixmapItem; class UBGraphicsPixmapItem;
class UBGraphicsPDFItem; class UBGraphicsPDFItem;
class UBGraphicsWidgetItem; class UBGraphicsWidgetItem;
@ -125,6 +126,8 @@ class UBSvgSubsetAdaptor
QList<UBGraphicsPolygonItem*> polygonItemsFromPolylineSvg(const QColor& pDefaultColor); QList<UBGraphicsPolygonItem*> polygonItemsFromPolylineSvg(const QColor& pDefaultColor);
UBGraphicsLineItem* lineItemFromLineSvg(const QColor& pDefaultPenColor);
UBGraphicsPixmapItem* pixmapItemFromSvg(); UBGraphicsPixmapItem* pixmapItemFromSvg();
UBGraphicsSvgItem* svgItemFromSvg(); UBGraphicsSvgItem* svgItemFromSvg();
@ -195,6 +198,7 @@ class UBSvgSubsetAdaptor
void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument); void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument);
void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo);
void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo);
void lineItemToSvgLine(UBGraphicsLineItem* lineItem, bool groupHoldsInfo);
void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo);
void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo);

@ -300,6 +300,7 @@ QRectF UBBoardController::controlGeometry()
void UBBoardController::setupToolbar() void UBBoardController::setupToolbar()
{ {
QAction* newPropertyPaletteWidget;
UBSettings *settings = UBSettings::settings(); UBSettings *settings = UBSettings::settings();
// Setup color choice widget // Setup color choice widget
@ -314,7 +315,7 @@ void UBBoardController::setupToolbar()
new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions);
colorChoice->setLabel(tr("Color")); colorChoice->setLabel(tr("Color"));
mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice);
connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant)));
connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int)));
@ -327,6 +328,7 @@ void UBBoardController::setupToolbar()
colorChoice->colorPaletteChanged(); colorChoice->colorPaletteChanged();
colorChoice->setCurrentIndex(settings->penColorIndex()); colorChoice->setCurrentIndex(settings->penColorIndex());
colorActions.at(settings->penColorIndex())->setChecked(true); colorActions.at(settings->penColorIndex())->setChecked(true);
mPropertyPaletteWidgets.insert(color, newPropertyPaletteWidget);
// Setup line width choice widget // Setup line width choice widget
QList<QAction *> lineWidthActions; QList<QAction *> lineWidthActions;
@ -349,7 +351,8 @@ void UBBoardController::setupToolbar()
lineWidthChoice->setCurrentIndex(settings->penWidthIndex()); lineWidthChoice->setCurrentIndex(settings->penWidthIndex());
lineWidthActions.at(settings->penWidthIndex())->setChecked(true); lineWidthActions.at(settings->penWidthIndex())->setChecked(true);
mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice);
mPropertyPaletteWidgets.insert(lineWidth, newPropertyPaletteWidget);
//-----------------------------------------------------------// //-----------------------------------------------------------//
// Setup eraser width choice widget // Setup eraser width choice widget
@ -362,7 +365,7 @@ void UBBoardController::setupToolbar()
UBToolbarButtonGroup *eraserWidthChoice = UBToolbarButtonGroup *eraserWidthChoice =
new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions);
mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice);
connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant)));
connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int)));
@ -372,11 +375,32 @@ void UBBoardController::setupToolbar()
eraserWidthActions.at(settings->eraserWidthIndex())->setChecked(true); eraserWidthActions.at(settings->eraserWidthIndex())->setChecked(true);
mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds);
mPropertyPaletteWidgets.insert(eraserWidth, newPropertyPaletteWidget);
//-----------------------------------------------------------// //-----------------------------------------------------------//
// Setup line style choice widget
QList<QAction *> lineStyleActions;
lineStyleActions.append(mMainWindow->actionLineSolid);
lineStyleActions.append(mMainWindow->actionLineDashed);
lineStyleActions.append(mMainWindow->actionLineDotted);
UBToolbarButtonGroup *lineStyleChoice =
new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineStyleActions);
connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineStyleChoice, SLOT(displayText(QVariant)));
connect(lineStyleChoice, SIGNAL(activated(int)),
UBDrawingController::drawingController(), SLOT(setLineStyleIndex(int)));
UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); lineStyleChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool()));
newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineStyleChoice);
lineStyleChoice->setCurrentIndex(settings->lineStyleIndex());
lineStyleActions.at(settings->lineStyleIndex())->setChecked(true);
mPropertyPaletteWidgets.insert(lineStyle, newPropertyPaletteWidget);
//-----------------------------------------------------------//
UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBackgrounds);
UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard, 40);
UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu);
mMainWindow->actionBoard->setVisible(false); mMainWindow->actionBoard->setVisible(false);
@ -2185,9 +2209,9 @@ void UBBoardController::saveViewState()
void UBBoardController::stylusToolChanged(int tool) void UBBoardController::stylusToolChanged(int tool)
{ {
UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool;
if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette)
{ {
UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool;
if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text)
{ {
if(mPaletteManager->mKeyboardPalette->m_isVisible) if(mPaletteManager->mKeyboardPalette->m_isVisible)
@ -2201,6 +2225,34 @@ void UBBoardController::stylusToolChanged(int tool)
} }
} }
} }
if (eTool == UBStylusTool::Pen || eTool == UBStylusTool::Marker)
{
mPropertyPaletteWidgets[color]->setVisible(true);
mPropertyPaletteWidgets[lineWidth]->setVisible(true);
mPropertyPaletteWidgets[eraserWidth]->setVisible(false);
mPropertyPaletteWidgets[lineStyle]->setVisible(false);
} else
if (eTool == UBStylusTool::Eraser)
{
mPropertyPaletteWidgets[color]->setVisible(false);
mPropertyPaletteWidgets[lineWidth]->setVisible(false);
mPropertyPaletteWidgets[eraserWidth]->setVisible(true);
mPropertyPaletteWidgets[lineStyle]->setVisible(false);
} else
if (eTool == UBStylusTool::Line)
{
mPropertyPaletteWidgets[color]->setVisible(true);
mPropertyPaletteWidgets[lineWidth]->setVisible(true);
mPropertyPaletteWidgets[eraserWidth]->setVisible(false);
mPropertyPaletteWidgets[lineStyle]->setVisible(true);
} else
{
mPropertyPaletteWidgets[color]->setVisible(false);
mPropertyPaletteWidgets[lineWidth]->setVisible(false);
mPropertyPaletteWidgets[eraserWidth]->setVisible(false);
mPropertyPaletteWidgets[lineStyle]->setVisible(false);
}
} }

@ -322,6 +322,15 @@ class UBBoardController : public UBDocumentContainer
QTimer *mAutosaveTimer; QTimer *mAutosaveTimer;
enum PropertyPalette
{
color,
lineWidth,
eraserWidth,
lineStyle
};
QMap<PropertyPalette, QAction*> mPropertyPaletteWidgets;
private slots: private slots:
void stylusToolDoubleClicked(int tool); void stylusToolDoubleClicked(int tool);
void boardViewResized(QResizeEvent* event); void boardViewResized(QResizeEvent* event);

@ -67,6 +67,7 @@
#include "domain/UBGraphicsWidgetItem.h" #include "domain/UBGraphicsWidgetItem.h"
#include "domain/UBGraphicsPDFItem.h" #include "domain/UBGraphicsPDFItem.h"
#include "domain/UBGraphicsPolygonItem.h" #include "domain/UBGraphicsPolygonItem.h"
#include "domain/UBGraphicsLineItem.h"
#include "domain/UBItem.h" #include "domain/UBItem.h"
#include "domain/UBGraphicsMediaItem.h" #include "domain/UBGraphicsMediaItem.h"
#include "domain/UBGraphicsSvgItem.h" #include "domain/UBGraphicsSvgItem.h"
@ -1104,7 +1105,7 @@ void UBBoardView::mousePressEvent (QMouseEvent *event)
break; break;
default: default:
if(UBDrawingController::drawingController()->mActiveRuler==NULL) { if (UBDrawingController::drawingController()->activeRuler() == nullptr) {
viewport()->setCursor (QCursor (Qt::BlankCursor)); viewport()->setCursor (QCursor (Qt::BlankCursor));
} }
if (scene () && !mTabletStylusIsPressed) { if (scene () && !mTabletStylusIsPressed) {
@ -1210,7 +1211,8 @@ void UBBoardView::mouseMoveEvent (QMouseEvent *event)
|| item->type() == UBGraphicsSvgItem::Type || item->type() == UBGraphicsSvgItem::Type
|| item->type() == UBGraphicsTextItem::Type || item->type() == UBGraphicsTextItem::Type
|| item->type() == UBGraphicsStrokesGroup::Type || item->type() == UBGraphicsStrokesGroup::Type
|| item->type() == UBGraphicsGroupContainerItem::Type) { || item->type() == UBGraphicsGroupContainerItem::Type
|| item->type() == UBGraphicsLineItem::Type) {
if (!mJustSelectedItems.contains(item)) { if (!mJustSelectedItems.contains(item)) {

@ -34,6 +34,7 @@
#include "domain/UBGraphicsScene.h" #include "domain/UBGraphicsScene.h"
#include "board/UBBoardController.h" #include "board/UBBoardController.h"
#include "tools/UBAbstractDrawRuler.h"
#include "gui/UBMainWindow.h" #include "gui/UBMainWindow.h"
#include "core/memcheck.h" #include "core/memcheck.h"
@ -58,7 +59,6 @@ void UBDrawingController::destroy()
UBDrawingController::UBDrawingController(QObject * parent) UBDrawingController::UBDrawingController(QObject * parent)
: QObject(parent) : QObject(parent)
, mActiveRuler(NULL)
, mStylusTool((UBStylusTool::Enum)-1) , mStylusTool((UBStylusTool::Enum)-1)
, mLatestDrawingTool((UBStylusTool::Enum)-1) , mLatestDrawingTool((UBStylusTool::Enum)-1)
, mIsDesktopMode(false) , mIsDesktopMode(false)
@ -279,6 +279,11 @@ void UBDrawingController::setEraserWidthIndex(int index)
UBSettings::settings()->setEraserWidthIndex(index); UBSettings::settings()->setEraserWidthIndex(index);
} }
void UBDrawingController::setLineStyleIndex(int index)
{
UBSettings::settings()->setLineStyleIndex(index);
}
void UBDrawingController::setPenColor(bool onDarkBackground, const QColor& color, int pIndex) void UBDrawingController::setPenColor(bool onDarkBackground, const QColor& color, int pIndex)
{ {
if (onDarkBackground) if (onDarkBackground)
@ -322,6 +327,23 @@ void UBDrawingController::setMarkerAlpha(qreal alpha)
emit colorPaletteChanged(); emit colorPaletteChanged();
} }
void UBDrawingController::setActiveRuler(UBAbstractDrawRuler* ruler)
{
mActiveRuler = ruler;
}
UBAbstractDrawRuler* UBDrawingController::activeRuler() const
{
QGraphicsItem* item = dynamic_cast<QGraphicsItem*>(mActiveRuler.data());
if (item && item->isVisible())
{
return mActiveRuler;
}
return nullptr;
}
void UBDrawingController::penToolSelected(bool checked) void UBDrawingController::penToolSelected(bool checked)
{ {

@ -64,7 +64,8 @@ class UBDrawingController : public QObject
void setMarkerColor(bool onDarkBackground, const QColor& color, int pIndex); void setMarkerColor(bool onDarkBackground, const QColor& color, int pIndex);
void setMarkerAlpha(qreal alpha); void setMarkerAlpha(qreal alpha);
UBAbstractDrawRuler* mActiveRuler; void setActiveRuler(UBAbstractDrawRuler* ruler);
UBAbstractDrawRuler* activeRuler() const;
void setInDesktopMode(bool mode){ void setInDesktopMode(bool mode){
mIsDesktopMode = mode; mIsDesktopMode = mode;
@ -80,6 +81,7 @@ class UBDrawingController : public QObject
void setLineWidthIndex(int index); void setLineWidthIndex(int index);
void setColorIndex(int index); void setColorIndex(int index);
void setEraserWidthIndex(int index); void setEraserWidthIndex(int index);
void setLineStyleIndex(int index);
signals: signals:
void stylusToolChanged(int tool, int previousTool = -1); void stylusToolChanged(int tool, int previousTool = -1);
@ -89,6 +91,7 @@ class UBDrawingController : public QObject
void colorIndexChanged(int index); void colorIndexChanged(int index);
private: private:
QPointer<UBAbstractDrawRuler> mActiveRuler;
UBStylusTool::Enum mStylusTool; UBStylusTool::Enum mStylusTool;
UBStylusTool::Enum mLatestDrawingTool; UBStylusTool::Enum mLatestDrawingTool;
bool mIsDesktopMode; bool mIsDesktopMode;

@ -84,6 +84,16 @@ struct UBWidth
}; };
}; };
struct UBLineStyle
{
enum Enum
{
Solid = 0,
Dashed = 1,
Dotted = 2
};
};
struct UBZoom struct UBZoom
{ {
enum Enum enum Enum
@ -173,6 +183,7 @@ struct UBGraphicsItemType
GraphicsWidgetItemType, //65556 GraphicsWidgetItemType, //65556
UserTypesCount, //65557 UserTypesCount, //65557
AxesItemType, //65558 AxesItemType, //65558
LineItemType, //65559
SelectionFrameType // this line must be the last line in this enum because it is types counter. SelectionFrameType // this line must be the last line in this enum because it is types counter.
}; };
}; };

@ -785,6 +785,41 @@ qreal UBSettings::currentEraserWidth()
return width; return width;
} }
//----------------------------------------//
// line
int UBSettings::lineStyleIndex()
{
return value("Board/LineStyleIndex", 0).toInt();
}
void UBSettings::setLineStyleIndex(int index)
{
setValue("Board/LineStyleIndex", index);
}
Qt::PenStyle UBSettings::currentLineStyle()
{
Qt::PenStyle style = Qt::SolidLine;
switch (lineStyleIndex())
{
case UBLineStyle::Solid:
style = Qt::SolidLine;
break;
case UBLineStyle::Dotted:
style = Qt::DotLine;
break;
case UBLineStyle::Dashed:
style = Qt::DashLine;
break;
default:
Q_ASSERT(false);
style = Qt::SolidLine;
break;
}
return style;
}
bool UBSettings::isDarkBackground() bool UBSettings::isDarkBackground()
{ {
return value("Board/DarkBackground", 0).toBool(); return value("Board/DarkBackground", 0).toBool();

@ -85,6 +85,10 @@ class UBSettings : public QObject
qreal eraserStrongWidth(); qreal eraserStrongWidth();
qreal currentEraserWidth(); qreal currentEraserWidth();
// Line related
int lineStyleIndex();
Qt::PenStyle currentLineStyle();
// Background related // Background related
bool isDarkBackground(); bool isDarkBackground();
UBPageBackground pageBackground(); UBPageBackground pageBackground();
@ -443,6 +447,8 @@ class UBSettings : public QObject
void setEraserMediumWidth(qreal width); void setEraserMediumWidth(qreal width);
void setEraserStrongWidth(qreal width); void setEraserStrongWidth(qreal width);
void setLineStyleIndex(int index);
void setStylusPaletteVisible(bool visible); void setStylusPaletteVisible(bool visible);
void setPenPressureSensitive(bool sensitive); void setPenPressureSensitive(bool sensitive);

@ -0,0 +1,191 @@
#include "UBGraphicsLineItem.h"
#include "frameworks/UBGeometryUtils.h"
#include "UBGraphicsScene.h"
#include "core/memcheck.h"
UBGraphicsLineItem::UBGraphicsLineItem (QGraphicsItem * parent)
: QGraphicsLineItem(parent)
, mHasAlpha(false)
, mOriginalWidth(-1)
, mIsNominalLine(false)
{
// NOOP
initialize();
}
UBGraphicsLineItem::UBGraphicsLineItem (const QLineF & line, QGraphicsItem * parent)
: QGraphicsLineItem(line, parent)
, mOriginalWidth(-1)
, mIsNominalLine(false)
{
// NOOP
initialize();
}
UBGraphicsLineItem::UBGraphicsLineItem (const QLineF& pLine, qreal pWidth)
: QGraphicsLineItem(pLine)
, mOriginalLine(pLine)
, mOriginalWidth(pWidth)
, mIsNominalLine(true)
{
// NOOP
initialize();
}
UBGraphicsLineItem::UBGraphicsLineItem (const QLineF& pLine, qreal pStartWidth, qreal pEndWidth)
: QGraphicsLineItem(pLine)
, mOriginalLine(pLine)
, mOriginalWidth(pEndWidth)
, mIsNominalLine(true)
{
// NOOP
initialize();
}
void UBGraphicsLineItem::initialize()
{
//setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::DrawingItem)); //Necessary to set if we want z value to be assigned correctly
setDelegate(new UBGraphicsItemDelegate(this, 0, GF_COMMON
| GF_RESPECT_RATIO
| GF_REVOLVABLE
| GF_FLIPPABLE_ALL_AXIS));
setUuid(QUuid::createUuid());
setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemIsMovable, true);
}
void UBGraphicsLineItem::setUuid(const QUuid &pUuid)
{
UBItem::setUuid(pUuid);
setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene
}
UBGraphicsLineItem::~UBGraphicsLineItem()
{
}
void UBGraphicsLineItem::setColor(const QColor& pColor)
{
QPen pen = QPen(pColor);
pen.setStyle(style());
if (style()==Qt::PenStyle::DotLine)
{
pen.setCapStyle(Qt::PenCapStyle::RoundCap);
}
pen.setWidth(mOriginalWidth);
QGraphicsLineItem::setPen(pen);
mHasAlpha = (pColor.alphaF() < 1.0);
}
QColor UBGraphicsLineItem::color() const
{
return QGraphicsLineItem::pen().color();
}
void UBGraphicsLineItem::setStyle(const Qt::PenStyle& style)
{
QPen pen = QPen(color());
pen.setStyle(style);
if (style==Qt::PenStyle::DotLine)
{
pen.setCapStyle(Qt::PenCapStyle::RoundCap);
}
pen.setWidth(mOriginalWidth);
QGraphicsLineItem::setPen(pen);
}
Qt::PenStyle UBGraphicsLineItem::style() const
{
return QGraphicsLineItem::pen().style();
}
QList<QPointF> UBGraphicsLineItem::linePoints()
{
QList<QPointF> points = QList<QPointF>();
qreal incr = 1/line().length();
if (incr<0) incr*=-1;
if (incr>0)
{
for (qreal t = 0; t <= 1; t+=incr)
{
points.push_back(line().pointAt(t));
}
}
return points;
}
UBItem* UBGraphicsLineItem::deepCopy() const
{
UBGraphicsLineItem* copy = new UBGraphicsLineItem(line());
copyItemParameters(copy);
return copy;
}
void UBGraphicsLineItem::copyItemParameters(UBItem *copy) const
{
UBGraphicsLineItem *cp = dynamic_cast<UBGraphicsLineItem*>(copy);
if (cp)
{
cp->mOriginalLine = this->mOriginalLine;
cp->mOriginalWidth = this->mOriginalWidth;
cp->mIsNominalLine = this->mIsNominalLine;
cp->setTransform(transform());
cp->setPos(pos());
cp->setPen(this->pen());
cp->mHasAlpha = this->mHasAlpha;
cp->setColorOnDarkBackground(this->colorOnDarkBackground());
cp->setColorOnLightBackground(this->colorOnLightBackground());
cp->setFlag(QGraphicsItem::ItemIsMovable, true);
cp->setFlag(QGraphicsItem::ItemIsSelectable, true);
cp->setZValue(this->zValue());
cp->setData(UBGraphicsItemData::ItemLayerType, this->data(UBGraphicsItemData::ItemLayerType));
cp->setData(UBGraphicsItemData::ItemLocked, this->data(UBGraphicsItemData::ItemLocked));
}
}
void UBGraphicsLineItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
QStyleOptionGraphicsItem styleOption = QStyleOptionGraphicsItem(*option);
if(mHasAlpha && scene() && scene()->isLightBackground())
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->setRenderHints(QPainter::Antialiasing);
QGraphicsLineItem::paint(painter, option, widget);
Delegate()->postpaint(painter, &styleOption, widget);
}
UBGraphicsScene* UBGraphicsLineItem::scene()
{
return qobject_cast<UBGraphicsScene*>(QGraphicsLineItem::scene());
}
void UBGraphicsLineItem::SetDelegate()
{
Delegate()->createControls();
}
QVariant UBGraphicsLineItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
QVariant newValue = Delegate()->itemChange(change, value);
UBGraphicsItem *item = dynamic_cast<UBGraphicsItem*>(this);
if (item)
{
item->Delegate()->positionHandles();
}
return QGraphicsItem::itemChange(change, newValue);
}

@ -0,0 +1,100 @@
#ifndef UBGRAPHICSLINEITEM_H
#define UBGRAPHICSLINEITEM_H
#include <QtGui>
#include "core/UB.h"
#include "UBItem.h"
class UBItem;
class UBGraphicsScene;
class UBGraphicsLineItem : public QGraphicsLineItem, public UBItem, public UBGraphicsItem
{
public:
UBGraphicsLineItem(QGraphicsItem * parent = 0 );
UBGraphicsLineItem(const QLineF& line, qreal pWidth);
UBGraphicsLineItem(const QLineF& pLine, qreal pStartWidth, qreal pEndWidth);
UBGraphicsLineItem(const QLineF & line, QGraphicsItem * parent = 0);
~UBGraphicsLineItem();
void initialize();
void setUuid(const QUuid &pUuid);
void setColor(const QColor& color);
void setStyle(const Qt::PenStyle& style);
QColor color() const;
Qt::PenStyle style() const;
virtual UBGraphicsScene* scene();
enum { Type = UBGraphicsItemType::LineItemType };
virtual int type() const
{
return Type;
}
void setLine(const QLineF pLine)
{
mIsNominalLine = false;
QGraphicsLineItem::setLine(pLine);
}
virtual UBItem* deepCopy() const;
virtual void copyItemParameters(UBItem *copy) const;
QLineF originalLine() { return mOriginalLine;}
qreal originalWidth() { return mOriginalWidth;}
bool isNominalLine() {return mIsNominalLine;}
void setNominalLine(bool isNominalLine) { mIsNominalLine = isNominalLine; }
QList<QPointF> linePoints();
QColor colorOnDarkBackground() const
{
return mColorOnDarkBackground;
}
void setColorOnDarkBackground(QColor pColorOnDarkBackground)
{
mColorOnDarkBackground = pColorOnDarkBackground;
}
QColor colorOnLightBackground() const
{
return mColorOnLightBackground;
}
void setColorOnLightBackground(QColor pColorOnLightBackground)
{
mColorOnLightBackground = pColorOnLightBackground;
}
void SetDelegate();
protected:
void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget);
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private:
bool mHasAlpha;
QLineF mOriginalLine;
qreal mOriginalWidth;
bool mIsNominalLine;
QColor mColorOnDarkBackground;
QColor mColorOnLightBackground;
};
#endif // UBGRAPHICSLINEITEM_H

@ -70,6 +70,7 @@
#include "UBGraphicsPixmapItem.h" #include "UBGraphicsPixmapItem.h"
#include "UBGraphicsSvgItem.h" #include "UBGraphicsSvgItem.h"
#include "UBGraphicsPolygonItem.h" #include "UBGraphicsPolygonItem.h"
#include "UBGraphicsLineItem.h"
#include "UBGraphicsMediaItem.h" #include "UBGraphicsMediaItem.h"
#include "UBGraphicsWidgetItem.h" #include "UBGraphicsWidgetItem.h"
#include "UBGraphicsPDFItem.h" #include "UBGraphicsPDFItem.h"
@ -451,8 +452,8 @@ bool UBGraphicsScene::inputDevicePress(const QPointF& scenePos, const qreal& pre
mAddedItems.clear(); mAddedItems.clear();
mRemovedItems.clear(); mRemovedItems.clear();
if (UBDrawingController::drawingController()->mActiveRuler) if (UBDrawingController::drawingController()->activeRuler())
UBDrawingController::drawingController()->mActiveRuler->StartLine(scenePos, width); UBDrawingController::drawingController()->activeRuler()->StartLine(scenePos, width);
else { else {
moveTo(scenePos); moveTo(scenePos);
drawLineTo(scenePos, width, UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line); drawLineTo(scenePos, width, UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line);
@ -539,25 +540,8 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
width /= UBApplication::boardController->systemScaleFactor(); width /= UBApplication::boardController->systemScaleFactor();
width /= UBApplication::boardController->currentZoom(); width /= UBApplication::boardController->currentZoom();
if (currentTool == UBStylusTool::Line || dc->mActiveRuler) if (currentTool == UBStylusTool::Line || dc->activeRuler())
{ {
if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker)
if(NULL != mpLastPolygon && NULL != mCurrentStroke && mAddedItems.size() > 0){
UBCoreGraphicsScene::removeItemFromDeletion(mpLastPolygon);
mAddedItems.remove(mpLastPolygon);
mCurrentStroke->remove(mpLastPolygon);
if (mCurrentStroke->polygons().empty()){
delete mCurrentStroke;
mCurrentStroke = NULL;
}
removeItem(mpLastPolygon);
mPreviousPolygonItems.removeAll(mpLastPolygon);
}
// ------------------------------------------------------------------------
// Here we wanna make sure that the Line will 'grip' at i*45, i*90 degrees
// ------------------------------------------------------------------------
QLineF radius(mPreviousPoint, position); QLineF radius(mPreviousPoint, position);
qreal angle = radius.angle(); qreal angle = radius.angle();
angle = qRound(angle / 45) * 45; angle = qRound(angle / 45) * 45;
@ -573,8 +557,8 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
if (!mCurrentStroke) if (!mCurrentStroke)
mCurrentStroke = new UBGraphicsStroke(this); mCurrentStroke = new UBGraphicsStroke(this);
if(dc->mActiveRuler){ if(dc->activeRuler()){
dc->mActiveRuler->DrawLine(position, width); dc->activeRuler()->DrawLine(position, width);
} }
else if (currentTool == UBStylusTool::Line) { else if (currentTool == UBStylusTool::Line) {
@ -667,7 +651,16 @@ bool UBGraphicsScene::inputDeviceRelease(int tool)
if (currentTool == UBStylusTool::Eraser) if (currentTool == UBStylusTool::Eraser)
hideEraser(); hideEraser();
if(currentTool == UBStylusTool::Line)
{
if (mUndoRedoStackEnabled)
{ //should be deleted after scene own undo stack implemented
UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(this, NULL, mpLastLine);
UBApplication::undoStack->push(uc);
mAddedItems.clear();
}
} else{
UBDrawingController *dc = UBDrawingController::drawingController(); UBDrawingController *dc = UBDrawingController::drawingController();
@ -741,6 +734,7 @@ bool UBGraphicsScene::inputDeviceRelease(int tool)
mCurrentPolygon = 0; mCurrentPolygon = 0;
} }
} }
}
if (mRemovedItems.size() > 0 || mAddedItems.size() > 0) if (mRemovedItems.size() > 0 || mAddedItems.size() > 0)
{ {
@ -859,7 +853,7 @@ void UBGraphicsScene::drawPenCircle(const QPointF &pPoint)
cursor = UBResources::resources()->penCursor; cursor = UBResources::resources()->penCursor;
} }
if (!UBDrawingController::drawingController()->mActiveRuler) if (!UBDrawingController::drawingController()->activeRuler())
{ {
// set cursor only if no active ruler // set cursor only if no active ruler
if (controlView() && controlView()->viewport()) if (controlView() && controlView()->viewport())
@ -943,8 +937,17 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &startWid
mAddedItems.clear(); mAddedItems.clear();
} }
UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line)
addPolygonItemToCurrentStroke(polygonItem); {
UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth);
addPolygonItemToCurrentStroke(polygonItem);
} else
{
UBGraphicsLineItem *lineItem = new UBGraphicsLineItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth);
initLineItem(lineItem);
addLineItemToCurrentStroke(lineItem);
}
if (!bLineStyle) { if (!bLineStyle) {
mPreviousPoint = pEndPoint; mPreviousPoint = pEndPoint;
@ -998,6 +1001,20 @@ void UBGraphicsScene::addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polyg
} }
void UBGraphicsScene::addLineItemToCurrentStroke(UBGraphicsLineItem* lineItem)
{
lineItem->setFlag(QGraphicsItem::ItemIsMovable, true);
lineItem->setFlag(QGraphicsItem::ItemIsSelectable, true);
lineItem->SetDelegate();
mpLastLine = lineItem;
mAddedItems.insert(lineItem);
// Here we add the item to the scene
addItem(lineItem);
}
void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
{ {
const QLineF line(mPreviousPoint, pEndPoint); const QLineF line(mPreviousPoint, pEndPoint);
@ -1017,13 +1034,15 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
typedef QList<QPolygonF> POLYGONSLIST; typedef QList<QPolygonF> POLYGONSLIST;
QList<POLYGONSLIST> intersectedPolygons; QList<POLYGONSLIST> intersectedPolygons;
QList<UBGraphicsLineItem*> intersectedLineItems;
#pragma omp parallel for #pragma omp parallel for
for(int i=0; i<collidItems.size(); i++) for(int i=0; i<collidItems.size(); i++)
{ {
UBGraphicsPolygonItem *pi = qgraphicsitem_cast<UBGraphicsPolygonItem*>(collidItems[i]); UBGraphicsPolygonItem *pi = qgraphicsitem_cast<UBGraphicsPolygonItem*>(collidItems[i]);
if(pi == NULL) UBGraphicsLineItem *li = qgraphicsitem_cast<UBGraphicsLineItem*>(collidItems[i]);
continue; if(pi != NULL)
{
QPainterPath itemPainterPath; QPainterPath itemPainterPath;
itemPainterPath.addPolygon(pi->sceneTransform().map(pi->polygon())); itemPainterPath.addPolygon(pi->sceneTransform().map(pi->polygon()));
@ -1046,6 +1065,23 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
intersectedPolygons << newPath.simplified().toFillPolygons(pi->sceneTransform().inverted()); intersectedPolygons << newPath.simplified().toFillPolygons(pi->sceneTransform().inverted());
} }
} }
} else if (li != NULL)
{
QPainterPath itemPainterPath;
QList<QPointF> linePoints = li->linePoints();
for (int i=0; i < linePoints.count(); ++i)
{
itemPainterPath.addEllipse(linePoints[i], 1, 1);
}
if (eraserPath.contains(itemPainterPath) || eraserPath.intersects(itemPainterPath))
{
#pragma omp critical
{
// Compete remove item
intersectedLineItems << li;
}
}
}
} }
for(int i=0; i<intersectedItems.size(); i++) for(int i=0; i<intersectedItems.size(); i++)
@ -1093,7 +1129,21 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
intersectedPolygonItem->setTransform(t); intersectedPolygonItem->setTransform(t);
} }
if (!intersectedItems.empty()) for (int i=0; i<intersectedLineItems.size(); i++)
{
UBGraphicsLineItem *intersectedLineItem = intersectedLineItems[i];
mRemovedItems << intersectedLineItem;
QTransform t;
bool bApplyTransform = false;
removeItem(intersectedLineItem);
if (bApplyTransform)
{
intersectedLineItem ->setTransform(t);
}
}
if (!intersectedItems.empty() || !intersectedLineItems.empty())
setModified(true); setModified(true);
} }
@ -1271,6 +1321,37 @@ void UBGraphicsScene::initPolygonItem(UBGraphicsPolygonItem* polygonItem)
polygonItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); polygonItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic));
} }
void UBGraphicsScene::initLineItem(UBGraphicsLineItem* lineItem)
{
QColor colorOnDarkBG;
QColor colorOnLightBG;
if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker)
{
colorOnDarkBG = UBApplication::boardController->penColorOnDarkBackground();
colorOnLightBG = UBApplication::boardController->penColorOnLightBackground();
}
if (mDarkBackground)
{
lineItem->setColor(colorOnDarkBG);
}
else
{
lineItem->setColor(colorOnLightBG);
}
lineItem->setColorOnDarkBackground(colorOnDarkBG);
lineItem->setColorOnLightBackground(colorOnLightBG);
lineItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic));
lineItem->setStyle(UBSettings::settings()->currentLineStyle());
QPen linePen = lineItem->pen();
linePen.setWidth(lineItem->originalWidth());
lineItem->setPen(linePen);
}
UBGraphicsPolygonItem* UBGraphicsScene::arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth) UBGraphicsPolygonItem* UBGraphicsScene::arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth)
{ {
QPolygonF polygon = UBGeometryUtils::arcToPolygon(pStartRadius, pSpanAngle, pWidth); QPolygonF polygon = UBGeometryUtils::arcToPolygon(pStartRadius, pSpanAngle, pWidth);
@ -1491,7 +1572,7 @@ void UBGraphicsScene::clearContent(clearCase pCase)
? qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(item->parentItem()) ? qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(item->parentItem())
: 0; : 0;
UBGraphicsItemDelegate *curDelegate = UBGraphicsItem::Delegate(item); UBGraphicsItemDelegate *curDelegate = UBGraphicsItem::Delegate(item);
if (!curDelegate) { if (!curDelegate && item->type() != UBGraphicsLineItem::Type) {
continue; continue;
} }
@ -1499,6 +1580,12 @@ void UBGraphicsScene::clearContent(clearCase pCase)
bool isStrokesGroup = item->type() == UBGraphicsStrokesGroup::Type; bool isStrokesGroup = item->type() == UBGraphicsStrokesGroup::Type;
bool shouldDelete = false; bool shouldDelete = false;
if(item->type()==UBGraphicsLineItem::Type)
{
removedItems << item;
this->removeItem(item);
} else
{
switch (static_cast<int>(pCase)) { switch (static_cast<int>(pCase)) {
case clearAnnotations : case clearAnnotations :
shouldDelete = isStrokesGroup; shouldDelete = isStrokesGroup;
@ -1510,6 +1597,7 @@ void UBGraphicsScene::clearContent(clearCase pCase)
shouldDelete = !isGroup && !isBackgroundObject(item); shouldDelete = !isGroup && !isBackgroundObject(item);
break; break;
} }
}
if(shouldDelete) { if(shouldDelete) {
if (itemGroup) { if (itemGroup) {

@ -41,6 +41,7 @@ class UBGraphicsPixmapItem;
class UBGraphicsProxyWidget; class UBGraphicsProxyWidget;
class UBGraphicsSvgItem; class UBGraphicsSvgItem;
class UBGraphicsPolygonItem; class UBGraphicsPolygonItem;
class UBGraphicsLineItem;
class UBGraphicsMediaItem; class UBGraphicsMediaItem;
class UBGraphicsWidgetItem; class UBGraphicsWidgetItem;
class UBGraphicsW3CWidgetItem; class UBGraphicsW3CWidgetItem;
@ -400,8 +401,11 @@ public slots:
UBGraphicsPolygonItem* curveToPolygonItem(const QList<QPair<QPointF, qreal> > &points); UBGraphicsPolygonItem* curveToPolygonItem(const QList<QPair<QPointF, qreal> > &points);
UBGraphicsPolygonItem* curveToPolygonItem(const QList<QPointF> &points, qreal startWidth, qreal endWidth); UBGraphicsPolygonItem* curveToPolygonItem(const QList<QPointF> &points, qreal startWidth, qreal endWidth);
void addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polygonItem); void addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polygonItem);
void addLineItemToCurrentStroke(UBGraphicsLineItem* lineItem);
void initPolygonItem(UBGraphicsPolygonItem*); void initPolygonItem(UBGraphicsPolygonItem*);
void initLineItem(UBGraphicsLineItem*);
void drawEraser(const QPointF& pEndPoint, bool pressed = true); void drawEraser(const QPointF& pEndPoint, bool pressed = true);
void redrawEraser(bool pressed); void redrawEraser(bool pressed);
@ -493,6 +497,7 @@ public slots:
UBZLayerController *mZLayerController; UBZLayerController *mZLayerController;
UBGraphicsPolygonItem* mpLastPolygon; UBGraphicsPolygonItem* mpLastPolygon;
UBGraphicsPolygonItem* mTempPolygon; UBGraphicsPolygonItem* mTempPolygon;
UBGraphicsLineItem* mpLastLine;
bool mDrawWithCompass; bool mDrawWithCompass;
UBGraphicsPolygonItem *mCurrentPolygon; UBGraphicsPolygonItem *mCurrentPolygon;

@ -41,6 +41,7 @@
#include "domain/UBGraphicsScene.h" #include "domain/UBGraphicsScene.h"
#include "tools/UBGraphicsCurtainItem.h" #include "tools/UBGraphicsCurtainItem.h"
#include "domain/UBGraphicsItemDelegate.h" #include "domain/UBGraphicsItemDelegate.h"
#include "domain/UBGraphicsLineItem.h"
UBItem::UBItem() UBItem::UBItem()
: mUuid(QUuid()) : mUuid(QUuid())
@ -135,6 +136,8 @@ UBGraphicsItemDelegate *UBGraphicsItem::Delegate(QGraphicsItem *pItem)
case UBGraphicsCurtainItem::Type : case UBGraphicsCurtainItem::Type :
result = (static_cast<UBGraphicsCurtainItem*>(pItem))->Delegate(); result = (static_cast<UBGraphicsCurtainItem*>(pItem))->Delegate();
break; break;
case UBGraphicsLineItem::Type :
result = (static_cast<UBGraphicsLineItem*>(pItem))->Delegate();
} }
return result; return result;

@ -6,6 +6,7 @@ HEADERS += src/domain/UBGraphicsScene.h \
src/domain/UBPageSizeUndoCommand.h \ src/domain/UBPageSizeUndoCommand.h \
src/domain/UBGraphicsProxyWidget.h \ src/domain/UBGraphicsProxyWidget.h \
src/domain/UBGraphicsSvgItem.h \ src/domain/UBGraphicsSvgItem.h \
src/domain/UBGraphicsLineItem.h \
src/domain/UBGraphicsPolygonItem.h \ src/domain/UBGraphicsPolygonItem.h \
src/domain/UBItem.h \ src/domain/UBItem.h \
src/domain/UBGraphicsWidgetItem.h \ src/domain/UBGraphicsWidgetItem.h \
@ -35,6 +36,7 @@ SOURCES += src/domain/UBGraphicsScene.cpp \
src/domain/UBPageSizeUndoCommand.cpp \ src/domain/UBPageSizeUndoCommand.cpp \
src/domain/UBGraphicsProxyWidget.cpp \ src/domain/UBGraphicsProxyWidget.cpp \
src/domain/UBGraphicsSvgItem.cpp \ src/domain/UBGraphicsSvgItem.cpp \
src/domain/UBGraphicsLineItem.cpp \
src/domain/UBGraphicsPolygonItem.cpp \ src/domain/UBGraphicsPolygonItem.cpp \
src/domain/UBItem.cpp \ src/domain/UBItem.cpp \
src/domain/UBGraphicsWidgetItem.cpp \ src/domain/UBGraphicsWidgetItem.cpp \

@ -420,9 +420,6 @@ void UBGraphicsRuler::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{ {
UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool ();
if (UBDrawingController::drawingController()->mActiveRuler == nullptr)
UBDrawingController::drawingController()->mActiveRuler = this;
if (currentTool == UBStylusTool::Selector || if (currentTool == UBStylusTool::Selector ||
currentTool == UBStylusTool::Play) currentTool == UBStylusTool::Play)
{ {
@ -453,6 +450,7 @@ void UBGraphicsRuler::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
else if (UBDrawingController::drawingController()->isDrawingTool()) else if (UBDrawingController::drawingController()->isDrawingTool())
{ {
setCursor(drawRulerLineCursor()); setCursor(drawRulerLineCursor());
UBDrawingController::drawingController()->setActiveRuler(this);
event->accept(); event->accept();
} }
} }
@ -464,7 +462,7 @@ void UBGraphicsRuler::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
mCloseSvgItem->setVisible(mShowButtons); mCloseSvgItem->setVisible(mShowButtons);
mResizeSvgItem->setVisible(mShowButtons); mResizeSvgItem->setVisible(mShowButtons);
mRotateSvgItem->setVisible(mShowButtons); mRotateSvgItem->setVisible(mShowButtons);
UBDrawingController::drawingController()->mActiveRuler = nullptr; UBDrawingController::drawingController()->setActiveRuler(nullptr);
event->accept(); event->accept();
update(); update();
} }

@ -886,7 +886,7 @@ void UBGraphicsTriangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
} else if (UBDrawingController::drawingController()->isDrawingTool()) { } else if (UBDrawingController::drawingController()->isDrawingTool()) {
setCursor(drawRulerLineCursor()); setCursor(drawRulerLineCursor());
UBDrawingController::drawingController()->mActiveRuler = this; UBDrawingController::drawingController()->setActiveRuler(this);
event->accept(); event->accept();
} }
@ -904,7 +904,7 @@ void UBGraphicsTriangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
mVFlipSvgItem->setVisible(false); mVFlipSvgItem->setVisible(false);
mHFlipSvgItem->setVisible(false); mHFlipSvgItem->setVisible(false);
mRotateSvgItem->setVisible(false); mRotateSvgItem->setVisible(false);
UBDrawingController::drawingController()->mActiveRuler = NULL; UBDrawingController::drawingController()->setActiveRuler(nullptr);
event->accept(); event->accept();
update(); update();
} }

Loading…
Cancel
Save