/*
* 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 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "UBGraphicsScene.h"
# include <QtGui>
# include <QtWebKit>
# include <QtSvg>
# include <QGraphicsView>
# include "frameworks/UBGeometryUtils.h"
# include "frameworks/UBPlatformUtils.h"
# include "core/UBApplication.h"
# include "core/UBSettings.h"
# include "core/UBApplicationController.h"
# include "core/UBDisplayManager.h"
# include "core/UBPersistenceManager.h"
# include "tools/UBGraphicsRuler.h"
# include "tools/UBGraphicsProtractor.h"
# include "tools/UBGraphicsCompass.h"
# include "tools/UBGraphicsTriangle.h"
# include "tools/UBGraphicsCurtainItem.h"
# include "document/UBDocumentProxy.h"
# include "board/UBBoardController.h"
# include "board/UBDrawingController.h"
# include "UBGraphicsItemUndoCommand.h"
# include "UBGraphicsTextItemUndoCommand.h"
# include "UBGraphicsProxyWidget.h"
# include "UBGraphicsPixmapItem.h"
# include "UBGraphicsSvgItem.h"
# include "UBGraphicsPolygonItem.h"
# include "UBGraphicsVideoItem.h"
# include "UBGraphicsAudioItem.h"
# include "UBGraphicsWidgetItem.h"
# include "UBGraphicsPDFItem.h"
# include "UBGraphicsTextItem.h"
# include "UBAppleWidget.h"
# include "UBW3CWidget.h"
# include "UBGraphicsStroke.h"
# include "core/memcheck.h"
qreal UBGraphicsScene : : backgroundLayerStart = - 20000000.0 ;
qreal UBGraphicsScene : : objectLayerStart = - 10000000.0 ;
qreal UBGraphicsScene : : drawingLayerStart = 0.0 ;
qreal UBGraphicsScene : : toolLayerStart = 10000000.0 ;
qreal UBGraphicsScene : : toolOffsetRuler = 100 ;
qreal UBGraphicsScene : : toolOffsetProtractor = 100 ;
qreal UBGraphicsScene : : toolOffsetTriangle = 100 ;
qreal UBGraphicsScene : : toolOffsetCompass = 100 ;
qreal UBGraphicsScene : : toolOffsetEraser = 200 ;
qreal UBGraphicsScene : : toolOffsetCurtain = 1000 ;
qreal UBGraphicsScene : : toolOffsetPointer = 1100 ;
UBGraphicsScene : : UBGraphicsScene ( UBDocumentProxy * parent )
: UBCoreGraphicsScene ( parent )
, mEraser ( 0 )
, mPointer ( 0 )
, mDocument ( parent )
, mDarkBackground ( false )
, mCrossedBackground ( false )
, mIsModified ( true )
, mBackgroundObject ( 0 )
, mPreviousWidth ( 0 )
, mInputDeviceIsPressed ( false )
, mArcPolygonItem ( 0 )
, mRenderingContext ( Screen )
, mCurrentStroke ( 0 )
, mShouldUseOMP ( true )
, mItemCount ( 0 )
{
# ifdef __ppc__
mShouldUseOMP = false ;
# elif defined(Q_WS_MAC)
mShouldUseOMP = QSysInfo : : MacintoshVersion > = QSysInfo : : MV_10_5 ;
# endif
setDocument ( parent ) ;
mDrawingZIndex = drawingLayerStart ;
mObjectZIndex = objectLayerStart ;
mEraser = new QGraphicsEllipseItem ( ) ; // mem : owned and destroyed by the scene
mEraser - > setRect ( QRect ( 0 , 0 , 0 , 0 ) ) ;
mEraser - > setVisible ( false ) ;
mEraser - > setZValue ( toolLayerStart + toolOffsetEraser ) ;
mEraser - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Control ) ) ;
mTools < < mEraser ;
addItem ( mEraser ) ;
mPointer = new QGraphicsEllipseItem ( ) ; // mem : owned and destroyed by the scene
mPointer - > setRect ( QRect ( 0 , 0 , 20 , 20 ) ) ;
mPointer - > setVisible ( false ) ;
mPointer - > setPen ( Qt : : NoPen ) ;
mPointer - > setBrush ( QBrush ( QColor ( 255 , 0 , 0 , 186 ) ) ) ;
mPointer - > setZValue ( toolLayerStart + toolOffsetPointer ) ;
mPointer - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Tool ) ) ;
mTools < < mPointer ;
addItem ( mPointer ) ;
if ( UBApplication : : applicationController )
{
setViewState ( SceneViewState ( 1 ,
UBApplication : : applicationController - > initialHScroll ( ) ,
UBApplication : : applicationController - > initialVScroll ( ) ) ) ;
}
connect ( this , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( selectionChangedProcessing ( ) ) ) ;
}
UBGraphicsScene : : ~ UBGraphicsScene ( )
{
// NOOP
}
void UBGraphicsScene : : selectionChangedProcessing ( )
{
QList < QGraphicsItem * > allItemsList = items ( ) ;
for ( int i = 0 ; i < allItemsList . size ( ) ; i + + )
{
QGraphicsItem * nextItem = allItemsList . at ( i ) ;
qreal zValue = nextItem - > zValue ( ) ;
nextItem - > setZValue ( qreal ( 1 ) ) ;
qDebug ( ) < < QString ( " %1 " ) . arg ( i ) < < QString ( " %1 " ) . arg ( zValue ) ;
}
QList < QGraphicsItem * > selItemsList = selectedItems ( ) ;
for ( int i = 0 ; i < selItemsList . size ( ) ; i + + )
{
QGraphicsItem * nextItem = selItemsList . at ( i ) ;
qreal zValue = nextItem - > zValue ( ) ;
nextItem - > setZValue ( 2 ) ;
qDebug ( ) < < QString ( " >>> %1 <<< " ) . arg ( i ) < < QString ( " >>> %1 <<< " ) . arg ( zValue ) ;
}
}
// MARK: -
// MARK: Mouse/Tablet events handling
bool UBGraphicsScene : : inputDevicePress ( const QPointF & scenePos , const qreal & pressure )
{
//mMesure1Ms = 0;
//mMesure2Ms = 0;
bool accepted = false ;
if ( mInputDeviceIsPressed )
{
qWarning ( ) < < " scene received input device pressed, without input device release, muting event as input device move " ;
accepted = inputDeviceMove ( scenePos , pressure ) ;
}
else
{
mInputDeviceIsPressed = true ;
UBStylusTool : : Enum currentTool = ( UBStylusTool : : Enum ) UBDrawingController : : drawingController ( ) - > stylusTool ( ) ;
if ( UBDrawingController : : drawingController ( ) - > isDrawingTool ( ) )
{
qreal width = 0 ;
mCurrentStroke = new UBGraphicsStroke ( ) ;
if ( currentTool ! = UBStylusTool : : Line )
width = UBDrawingController : : drawingController ( ) - > currentToolWidth ( ) * pressure ;
else
width = UBDrawingController : : drawingController ( ) - > currentToolWidth ( ) ; //ignore pressure for line tool
width / = UBApplication : : boardController - > systemScaleFactor ( ) ;
width / = UBApplication : : boardController - > currentZoom ( ) ;
mAddedItems . clear ( ) ;
mRemovedItems . clear ( ) ;
if ( UBDrawingController : : drawingController ( ) - > mActiveRuler )
{
UBDrawingController : : drawingController ( ) - > mActiveRuler - > StartLine (
scenePos , width ) ;
}
else
{
moveTo ( scenePos ) ;
drawLineTo ( scenePos , width ,
UBDrawingController : : drawingController ( ) - > stylusTool ( ) = = UBStylusTool : : Line ) ;
}
accepted = true ;
}
else if ( currentTool = = UBStylusTool : : Eraser )
{
mAddedItems . clear ( ) ;
mRemovedItems . clear ( ) ;
moveTo ( scenePos ) ;
qreal eraserWidth = UBSettings : : settings ( ) - > currentEraserWidth ( ) ;
eraserWidth / = UBApplication : : boardController - > systemScaleFactor ( ) ;
eraserWidth / = UBApplication : : boardController - > currentZoom ( ) ;
eraseLineTo ( scenePos , eraserWidth ) ;
accepted = true ;
}
else if ( currentTool = = UBStylusTool : : Pointer )
{
drawPointer ( scenePos ) ;
accepted = true ;
}
}
return accepted ;
}
bool UBGraphicsScene : : inputDeviceMove ( const QPointF & scenePos , const qreal & pressure )
{
bool accepted = false ;
UBDrawingController * dc = UBDrawingController : : drawingController ( ) ;
UBStylusTool : : Enum currentTool = ( UBStylusTool : : Enum ) dc - > stylusTool ( ) ;
QPointF position = QPointF ( scenePos ) ;
if ( currentTool = = UBStylusTool : : Eraser )
{
drawEraser ( position ) ;
accepted = true ;
}
if ( mInputDeviceIsPressed )
{
if ( dc - > isDrawingTool ( ) )
{
qreal width = 0 ;
if ( currentTool ! = UBStylusTool : : Line )
width = dc - > currentToolWidth ( ) * pressure ;
else
width = dc - > currentToolWidth ( ) ; //ignore pressure for line tool
width / = UBApplication : : boardController - > systemScaleFactor ( ) ;
width / = UBApplication : : boardController - > currentZoom ( ) ;
if ( dc - > mActiveRuler )
{
dc - > mActiveRuler - > DrawLine ( position , width ) ;
}
else
{
if ( currentTool = = UBStylusTool : : Line )
{
// TODO: Verify this beautiful implementation and check if
// it is possible to optimize it
QLineF radius ( mPreviousPoint , position ) ;
qreal angle = radius . angle ( ) ;
angle = qRound ( angle / 45 ) * 45 ;
qreal radiusLength = radius . length ( ) ;
QPointF newPosition (
mPreviousPoint . x ( ) + radiusLength * cos ( ( angle * PI ) / 180 ) ,
mPreviousPoint . y ( ) - radiusLength * sin ( ( angle * PI ) / 180 ) ) ;
QLineF chord ( position , newPosition ) ;
if ( chord . length ( ) < qMin ( ( int ) 16 , ( int ) ( radiusLength / 20 ) ) )
position = newPosition ;
}
drawLineTo ( position , width ,
UBDrawingController : : drawingController ( ) - > stylusTool ( ) = = UBStylusTool : : Line ) ;
}
}
else if ( currentTool = = UBStylusTool : : Eraser )
{
qreal eraserWidth = UBSettings : : settings ( ) - > currentEraserWidth ( ) ;
eraserWidth / = UBApplication : : boardController - > systemScaleFactor ( ) ;
eraserWidth / = UBApplication : : boardController - > currentZoom ( ) ;
eraseLineTo ( position , eraserWidth ) ;
}
else if ( currentTool = = UBStylusTool : : Pointer )
{
drawPointer ( position ) ;
}
accepted = true ;
}
return accepted ;
}
bool UBGraphicsScene : : inputDeviceRelease ( )
{
/*
if ( mMesure1Ms > 0 | | mMesure2Ms > 0 )
{
qWarning ( ) < < " --------------------------- " ;
qWarning ( ) < < " mMesure1Ms: " < < mMesure1Ms ;
qWarning ( ) < < " mMesure2Ms: " < < mMesure2Ms ;
mMesure1Ms = 0 ;
mMesure2Ms = 0 ;
}
*/
bool accepted = false ;
if ( mPointer )
{
mPointer - > hide ( ) ;
accepted = true ;
}
if ( UBDrawingController : : drawingController ( ) - > isDrawingTool ( ) )
{
mCurrentStroke = 0 ;
}
if ( mRemovedItems . size ( ) > 0 | | mAddedItems . size ( ) > 0 )
{
UBGraphicsItemUndoCommand * udcmd = new UBGraphicsItemUndoCommand ( this , mRemovedItems , mAddedItems ) ; //deleted by the undoStack
if ( UBApplication : : undoStack )
UBApplication : : undoStack - > push ( udcmd ) ;
mRemovedItems . clear ( ) ;
mAddedItems . clear ( ) ;
accepted = true ;
}
mInputDeviceIsPressed = false ;
setDocumentUpdated ( ) ;
return accepted ;
}
// MARK: -
void UBGraphicsScene : : drawEraser ( const QPointF & pPoint )
{
qreal eraserWidth = UBSettings : : settings ( ) - > currentEraserWidth ( ) ;
eraserWidth / = UBApplication : : boardController - > systemScaleFactor ( ) ;
eraserWidth / = UBApplication : : boardController - > currentZoom ( ) ;
qreal eraserRadius = eraserWidth / 2 ;
// TODO UB 4.x optimize - no need to do that every time we move it
if ( mEraser )
{
mEraser - > setRect ( QRectF ( pPoint . x ( ) - eraserRadius , pPoint . y ( ) - eraserRadius , eraserWidth , eraserWidth ) ) ;
mEraser - > show ( ) ;
}
}
void UBGraphicsScene : : drawPointer ( const QPointF & pPoint )
{
qreal pointerDiameter = UBSettings : : pointerDiameter / UBApplication : : boardController - > currentZoom ( ) ;
qreal pointerRadius = pointerDiameter / 2 ;
// TODO UB 4.x optimize - no need to do that every time we move it
if ( mPointer )
{
mPointer - > setRect ( QRectF ( pPoint . x ( ) - pointerRadius ,
pPoint . y ( ) - pointerRadius ,
pointerDiameter ,
pointerDiameter ) ) ;
mPointer - > show ( ) ;
}
}
void UBGraphicsScene : : moveTo ( const QPointF & pPoint )
{
mPreviousPoint = pPoint ;
mPreviousWidth = - 1.0 ;
mPreviousPolygonItems . clear ( ) ;
mArcPolygonItem = 0 ;
}
void UBGraphicsScene : : drawLineTo ( const QPointF & pEndPoint , const qreal & pWidth , bool bLineStyle )
{
if ( mPreviousWidth = = - 1.0 )
mPreviousWidth = pWidth ;
UBGraphicsPolygonItem * polygonItem = lineToPolygonItem ( QLineF ( mPreviousPoint , pEndPoint ) , pWidth ) ;
if ( ! polygonItem - > brush ( ) . isOpaque ( ) )
{
for ( int i = 0 ; i < mPreviousPolygonItems . size ( ) ; i + + )
{
UBGraphicsPolygonItem * previous = mPreviousPolygonItems . value ( i ) ;
polygonItem - > subtract ( previous ) ;
}
}
if ( bLineStyle )
{
QSetIterator < QGraphicsItem * > itItems ( mAddedItems ) ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * item = itItems . next ( ) ;
removeItem ( item ) ;
}
mAddedItems . clear ( ) ;
}
mAddedItems . insert ( polygonItem ) ;
if ( mCurrentStroke )
{
mCurrentStroke - > addPolygon ( polygonItem ) ;
polygonItem - > setStroke ( mCurrentStroke ) ;
}
addItem ( polygonItem ) ;
mPreviousPolygonItems . append ( polygonItem ) ;
if ( ! bLineStyle )
{
mPreviousPoint = pEndPoint ;
mPreviousWidth = pWidth ;
}
}
void UBGraphicsScene : : eraseLineTo ( const QPointF & pEndPoint , const qreal & pWidth )
{
const QLineF line ( mPreviousPoint , pEndPoint ) ;
const QPolygonF eraserPolygon = UBGeometryUtils : : lineToPolygon ( line , pWidth ) ;
const QRectF eraserBoundingRect = eraserPolygon . boundingRect ( ) ;
const QRectF eraserInnerRect = UBGeometryUtils : : lineToInnerRect ( line , pWidth ) ;
QPainterPath eraserPathVar ;
eraserPathVar . addPolygon ( eraserPolygon ) ;
const QPainterPath eraserPath = eraserPathVar ;
QList < QGraphicsItem * > collidItems = items ( eraserBoundingRect , Qt : : IntersectsItemBoundingRect ) ;
QSet < QGraphicsItem * > toBeAddedItems ;
QSet < QGraphicsItem * > toBeRemovedItems ;
int collidItemsSize = collidItems . size ( ) ;
toBeAddedItems . reserve ( collidItemsSize ) ;
toBeRemovedItems . reserve ( collidItemsSize ) ;
if ( mShouldUseOMP )
{
# pragma omp parallel for
for ( int i = 0 ; i < collidItemsSize ; i + + )
{
UBGraphicsPolygonItem * collidingPolygonItem
= qgraphicsitem_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
if ( collidingPolygonItem )
{
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
{
# pragma omp critical
toBeRemovedItems < < collidingPolygonItem ;
}
else
{
QPolygonF collidingPolygon = collidingPolygonItem - > polygon ( ) ;
QPainterPath collidingPath ;
collidingPath . addPolygon ( collidingPolygon ) ;
QPainterPath croppedPath = collidingPath . subtracted ( eraserPath ) ;
QPainterPath croppedPathSimplified = croppedPath . simplified ( ) ;
if ( croppedPath = = collidingPath )
{
// NOOP
}
else if ( croppedPathSimplified . isEmpty ( ) )
{
# pragma omp critical
toBeRemovedItems < < collidingPolygonItem ;
}
else
{
foreach ( const QPolygonF & pol , croppedPathSimplified . toFillPolygons ( ) )
{
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
# pragma omp critical
toBeAddedItems < < croppedPolygonItem ;
}
# pragma omp critical
toBeRemovedItems < < collidingPolygonItem ;
}
}
}
}
}
else
{
for ( int i = 0 ; i < collidItemsSize ; i + + )
{
UBGraphicsPolygonItem * collidingPolygonItem
= qgraphicsitem_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
if ( collidingPolygonItem )
{
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
{
toBeRemovedItems < < collidingPolygonItem ;
}
else
{
QPolygonF collidingPolygon = collidingPolygonItem - > polygon ( ) ;
QPainterPath collidingPath ;
collidingPath . addPolygon ( collidingPolygon ) ;
QPainterPath croppedPath = collidingPath . subtracted ( eraserPath ) ;
QPainterPath croppedPathSimplified = croppedPath . simplified ( ) ;
if ( croppedPath = = collidingPath )
{
// NOOP
}
else if ( croppedPathSimplified . isEmpty ( ) )
{
toBeRemovedItems < < collidingPolygonItem ;
}
else
{
foreach ( const QPolygonF & pol , croppedPathSimplified . toFillPolygons ( ) )
{
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
toBeAddedItems < < croppedPolygonItem ;
}
toBeRemovedItems < < collidingPolygonItem ;
}
}
}
}
}
addItems ( toBeAddedItems ) ;
mAddedItems + = toBeAddedItems ;
removeItems ( toBeRemovedItems ) ;
mRemovedItems + = toBeRemovedItems ;
mPreviousPoint = pEndPoint ;
}
void UBGraphicsScene : : drawArcTo ( const QPointF & pCenterPoint , qreal pSpanAngle )
{
if ( mArcPolygonItem )
{
mAddedItems . remove ( mArcPolygonItem ) ;
removeItem ( mArcPolygonItem ) ;
mArcPolygonItem = 0 ;
}
qreal penWidth = UBSettings : : settings ( ) - > currentPenWidth ( ) ;
penWidth / = UBApplication : : boardController - > systemScaleFactor ( ) ;
penWidth / = UBApplication : : boardController - > currentZoom ( ) ;
mArcPolygonItem = arcToPolygonItem ( QLineF ( pCenterPoint , mPreviousPoint ) , pSpanAngle , penWidth ) ;
mAddedItems . insert ( mArcPolygonItem ) ;
addItem ( mArcPolygonItem ) ;
setDocumentUpdated ( ) ;
}
qreal UBGraphicsScene : : getNextDrawingZIndex ( )
{
mDrawingZIndex = mDrawingZIndex + 1.0 ;
return mDrawingZIndex ;
}
qreal UBGraphicsScene : : getNextObjectZIndex ( )
{
mObjectZIndex = mObjectZIndex + 1.0 ;
return mObjectZIndex ;
}
void UBGraphicsScene : : setBackground ( bool pIsDark , bool pIsCrossed )
{
bool needRepaint = false ;
if ( mDarkBackground ! = pIsDark )
{
mDarkBackground = pIsDark ;
if ( mEraser )
{
if ( mDarkBackground )
{
mEraser - > setBrush ( UBSettings : : eraserBrushDarkBackground ) ;
mEraser - > setPen ( UBSettings : : eraserPenDarkBackground ) ;
}
else
{
mEraser - > setBrush ( UBSettings : : eraserBrushLightBackground ) ;
mEraser - > setPen ( UBSettings : : eraserPenLightBackground ) ;
}
}
recolorAllItems ( ) ;
needRepaint = true ;
setModified ( true ) ;
}
if ( mCrossedBackground ! = pIsCrossed )
{
mCrossedBackground = pIsCrossed ;
needRepaint = true ;
setModified ( true ) ;
}
if ( needRepaint )
{
foreach ( QGraphicsView * view , views ( ) )
{
view - > resetCachedContent ( ) ;
}
}
}
void UBGraphicsScene : : recolorAllItems ( )
{
QMap < QGraphicsView * , QGraphicsView : : ViewportUpdateMode > previousUpdateModes ;
foreach ( QGraphicsView * view , views ( ) )
{
previousUpdateModes . insert ( view , view - > viewportUpdateMode ( ) ) ;
view - > setViewportUpdateMode ( QGraphicsView : : NoViewportUpdate ) ;
}
for ( int i = 0 ; i < mFastAccessItems . size ( ) ; i + + )
{
UBGraphicsPolygonItem * polygonItem = qgraphicsitem_cast < UBGraphicsPolygonItem * > ( mFastAccessItems . at ( i ) ) ;
if ( polygonItem )
{
QColor color ;
if ( mDarkBackground )
{
color = polygonItem - > colorOnDarkBackground ( ) ;
}
else
{
color = polygonItem - > colorOnLightBackground ( ) ;
}
polygonItem - > setColor ( color ) ;
continue ;
}
}
foreach ( QGraphicsView * view , views ( ) )
{
view - > setViewportUpdateMode ( previousUpdateModes . value ( view ) ) ;
}
}
UBGraphicsPolygonItem * UBGraphicsScene : : lineToPolygonItem ( const QLineF & pLine , const qreal & pWidth )
{
UBGraphicsPolygonItem * polygonItem = new UBGraphicsPolygonItem ( pLine , pWidth ) ;
initPolygonItem ( polygonItem ) ;
return polygonItem ;
}
void UBGraphicsScene : : initPolygonItem ( UBGraphicsPolygonItem * polygonItem )
{
QColor colorOnDarkBG ;
QColor colorOnLightBG ;
if ( UBDrawingController : : drawingController ( ) - > stylusTool ( ) = = UBStylusTool : : Marker )
{
colorOnDarkBG = UBApplication : : boardController - > markerColorOnDarkBackground ( ) ;
colorOnLightBG = UBApplication : : boardController - > markerColorOnLightBackground ( ) ;
}
else // settings->stylusTool() == UBStylusTool::Pen + failsafe
{
colorOnDarkBG = UBApplication : : boardController - > penColorOnDarkBackground ( ) ;
colorOnLightBG = UBApplication : : boardController - > penColorOnLightBackground ( ) ;
}
if ( mDarkBackground )
{
polygonItem - > setColor ( colorOnDarkBG ) ;
}
else
{
polygonItem - > setColor ( colorOnLightBG ) ;
}
polygonItem - > setColorOnDarkBackground ( colorOnDarkBG ) ;
polygonItem - > setColorOnLightBackground ( colorOnLightBG ) ;
polygonItem - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Graphic ) ) ;
polygonItem - > setZValue ( getNextDrawingZIndex ( ) ) ;
}
UBGraphicsPolygonItem * UBGraphicsScene : : arcToPolygonItem ( const QLineF & pStartRadius , qreal pSpanAngle , qreal pWidth )
{
QPolygonF polygon = UBGeometryUtils : : arcToPolygon ( pStartRadius , pSpanAngle , pWidth ) ;
return polygonToPolygonItem ( polygon ) ;
}
UBGraphicsPolygonItem * UBGraphicsScene : : polygonToPolygonItem ( const QPolygonF pPolygon )
{
UBGraphicsPolygonItem * polygonItem = new UBGraphicsPolygonItem ( pPolygon ) ;
initPolygonItem ( polygonItem ) ;
return polygonItem ;
}
void UBGraphicsScene : : hideEraser ( )
{
if ( mEraser )
mEraser - > hide ( ) ;
}
void UBGraphicsScene : : leaveEvent ( QEvent * event )
{
Q_UNUSED ( event ) ;
hideEraser ( ) ;
}
UBGraphicsScene * UBGraphicsScene : : sceneDeepCopy ( ) const
{
UBGraphicsScene * copy = new UBGraphicsScene ( this - > document ( ) ) ;
copy - > setBackground ( this - > isDarkBackground ( ) , this - > isCrossedBackground ( ) ) ;
copy - > mDrawingZIndex = this - > mDrawingZIndex ;
copy - > mObjectZIndex = this - > mObjectZIndex ;
copy - > setSceneRect ( this - > sceneRect ( ) ) ;
if ( this - > mNominalSize . isValid ( ) )
copy - > setNominalSize ( this - > mNominalSize ) ;
QListIterator < QGraphicsItem * > itItems ( this - > mFastAccessItems ) ;
QMap < UBGraphicsStroke * , UBGraphicsStroke * > groupClone ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * item = itItems . next ( ) ;
QGraphicsItem * cloneItem = 0 ;
UBItem * ubItem = dynamic_cast < UBItem * > ( item ) ;
UBGraphicsStroke * stroke = dynamic_cast < UBGraphicsStroke * > ( item ) ;
if ( ubItem & & ! stroke )
{
cloneItem = dynamic_cast < QGraphicsItem * > ( ubItem - > deepCopy ( ) ) ;
}
if ( cloneItem )
{
copy - > addItem ( cloneItem ) ;
if ( isBackgroundObject ( item ) )
{
copy - > setAsBackgroundObject ( cloneItem ) ;
}
if ( this - > mTools . contains ( item ) )
{
copy - > mTools < < cloneItem ;
}
UBGraphicsPolygonItem * polygon = dynamic_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( polygon )
{
UBGraphicsStroke * stroke = dynamic_cast < UBGraphicsStroke * > ( item - > parentItem ( ) ) ;
if ( stroke )
{
UBGraphicsStroke * cloneStroke = groupClone . value ( stroke ) ;
if ( ! cloneStroke )
{
cloneStroke = stroke - > deepCopy ( ) ;
groupClone . insert ( stroke , cloneStroke ) ;
}
polygon - > setStroke ( cloneStroke ) ;
}
}
}
}
// TODO UB 4.7 ... complete all members ?
return copy ;
}
UBItem * UBGraphicsScene : : deepCopy ( ) const
{
return sceneDeepCopy ( ) ;
}
void UBGraphicsScene : : clearItemsAndAnnotations ( )
{
deselectAllItems ( ) ;
QSet < QGraphicsItem * > emptyList ;
QSet < QGraphicsItem * > removedItems ;
QListIterator < QGraphicsItem * > itItems ( mFastAccessItems ) ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * item = itItems . next ( ) ;
if ( ! mTools . contains ( item ) & & ! isBackgroundObject ( item ) )
{
removeItem ( item ) ;
removedItems < < item ;
}
}
// force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint
update ( sceneRect ( ) ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , removedItems , emptyList ) ;
UBApplication : : undoStack - > push ( uc ) ;
setDocumentUpdated ( ) ;
}
void UBGraphicsScene : : clearItems ( )
{
deselectAllItems ( ) ;
QSet < QGraphicsItem * > emptyList ;
QSet < QGraphicsItem * > removedItems ;
QListIterator < QGraphicsItem * > itItems ( mFastAccessItems ) ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * item = itItems . next ( ) ;
if ( ! item - > parentItem ( ) )
{
UBGraphicsPolygonItem * pi = qgraphicsitem_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( ! pi & & ! mTools . contains ( item ) & & ! isBackgroundObject ( item ) )
{
removeItem ( item ) ;
removedItems < < item ;
}
}
}
// force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint
update ( sceneRect ( ) ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , removedItems , emptyList ) ;
UBApplication : : undoStack - > push ( uc ) ;
setDocumentUpdated ( ) ;
}
void UBGraphicsScene : : clearAnnotations ( )
{
QSet < QGraphicsItem * > emptyList ;
QSet < QGraphicsItem * > removedItems ;
QListIterator < QGraphicsItem * > itItems ( mFastAccessItems ) ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * item = itItems . next ( ) ;
UBGraphicsPolygonItem * pi = qgraphicsitem_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( pi )
{
removeItem ( item ) ;
removedItems < < item ;
}
}
// force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint
update ( sceneRect ( ) ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , removedItems , emptyList ) ;
UBApplication : : undoStack - > push ( uc ) ;
setDocumentUpdated ( ) ;
}
UBGraphicsPixmapItem * UBGraphicsScene : : addPixmap ( const QPixmap & pPixmap , const QPointF & pPos , qreal pScaleFactor , bool pUseAnimation )
{
UBGraphicsPixmapItem * pixmapItem = new UBGraphicsPixmapItem ( ) ;
pixmapItem - > setFlag ( QGraphicsItem : : ItemIsMovable , true ) ;
pixmapItem - > setFlag ( QGraphicsItem : : ItemIsSelectable , true ) ;
pixmapItem - > setZValue ( getNextObjectZIndex ( ) ) ;
pixmapItem - > setPixmap ( pPixmap ) ;
QPointF half ( pPixmap . width ( ) * pScaleFactor / 2 , pPixmap . height ( ) * pScaleFactor / 2 ) ;
pixmapItem - > setPos ( pPos - half ) ;
addItem ( pixmapItem ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , pixmapItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
pixmapItem - > scale ( pScaleFactor , pScaleFactor ) ;
if ( pUseAnimation )
{
pixmapItem - > setOpacity ( 0 ) ;
QPropertyAnimation * animation = new QPropertyAnimation ( pixmapItem , " opacity " ) ;
animation - > setDuration ( 1000 ) ;
animation - > setStartValue ( 0.0 ) ;
animation - > setEndValue ( 1.0 ) ;
animation - > start ( ) ;
}
pixmapItem - > show ( ) ;
setDocumentUpdated ( ) ;
return pixmapItem ;
}
void UBGraphicsScene : : textUndoCommandAdded ( UBGraphicsTextItem * textItem )
{
UBGraphicsTextItemUndoCommand * uc = new UBGraphicsTextItemUndoCommand ( textItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
}
UBGraphicsVideoItem * UBGraphicsScene : : addVideo ( const QUrl & pVideoFileUrl , bool shouldPlayAsap , const QPointF & pPos )
{
UBGraphicsVideoItem * videoItem = new UBGraphicsVideoItem ( pVideoFileUrl ) ;
videoItem - > setPos ( pPos ) ;
videoItem - > setFlag ( QGraphicsItem : : ItemIsMovable , true ) ;
videoItem - > setFlag ( QGraphicsItem : : ItemIsSelectable , true ) ;
videoItem - > setZValue ( getNextObjectZIndex ( ) ) ;
addItem ( videoItem ) ;
videoItem - > show ( ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , videoItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
videoItem - > mediaObject ( ) - > play ( ) ;
if ( ! shouldPlayAsap )
{
videoItem - > mediaObject ( ) - > pause ( ) ;
videoItem - > mediaObject ( ) - > seek ( 0 ) ;
}
setDocumentUpdated ( ) ;
return videoItem ;
}
UBGraphicsAudioItem * UBGraphicsScene : : addAudio ( const QUrl & pAudioFileUrl , bool shouldPlayAsap , const QPointF & pPos )
{
UBGraphicsAudioItem * audioItem = new UBGraphicsAudioItem ( pAudioFileUrl ) ;
audioItem - > setPos ( pPos ) ;
audioItem - > setFlag ( QGraphicsItem : : ItemIsMovable , true ) ;
audioItem - > setFlag ( QGraphicsItem : : ItemIsSelectable , true ) ;
audioItem - > setZValue ( getNextObjectZIndex ( ) ) ;
addItem ( audioItem ) ;
audioItem - > show ( ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , audioItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
audioItem - > mediaObject ( ) - > play ( ) ;
if ( ! shouldPlayAsap )
{
audioItem - > mediaObject ( ) - > pause ( ) ;
audioItem - > mediaObject ( ) - > seek ( 0 ) ;
}
setDocumentUpdated ( ) ;
return audioItem ;
}
UBGraphicsWidgetItem * UBGraphicsScene : : addWidget ( const QUrl & pWidgetUrl , const QPointF & pPos )
{
int widgetType = UBAbstractWidget : : widgetType ( pWidgetUrl ) ;
if ( widgetType = = UBWidgetType : : Apple )
{
return addAppleWidget ( pWidgetUrl , pPos ) ;
}
else if ( widgetType = = UBWidgetType : : W3C )
{
return addW3CWidget ( pWidgetUrl , pPos ) ;
}
else
{
qDebug ( ) < < " UBGraphicsScene::addWidget: Unknown widget Type " ;
return 0 ;
}
}
UBGraphicsAppleWidgetItem * UBGraphicsScene : : addAppleWidget ( const QUrl & pWidgetUrl , const QPointF & pPos )
{
UBGraphicsAppleWidgetItem * appleWidget = new UBGraphicsAppleWidgetItem ( pWidgetUrl ) ;
addGraphicsWidget ( appleWidget , pPos ) ;
return appleWidget ;
}
UBGraphicsW3CWidgetItem * UBGraphicsScene : : addW3CWidget ( const QUrl & pWidgetUrl , const QPointF & pPos , int widgetType )
{
UBGraphicsW3CWidgetItem * w3CWidget = new UBGraphicsW3CWidgetItem ( pWidgetUrl , 0 , widgetType ) ;
addGraphicsWidget ( w3CWidget , pPos ) ;
return w3CWidget ;
}
void UBGraphicsScene : : addGraphicsWidget ( UBGraphicsWidgetItem * graphicsWidget , const QPointF & pPos )
{
graphicsWidget - > setFlag ( QGraphicsItem : : ItemIsSelectable , true ) ;
graphicsWidget - > setZValue ( getNextObjectZIndex ( ) ) ;
addItem ( graphicsWidget ) ;
qreal ssf = 1 / UBApplication : : boardController - > systemScaleFactor ( ) ;
graphicsWidget - > scale ( ssf , ssf ) ;
graphicsWidget - > setPos ( QPointF ( pPos . x ( ) - graphicsWidget - > boundingRect ( ) . width ( ) / 2 ,
pPos . y ( ) - graphicsWidget - > boundingRect ( ) . height ( ) / 2 ) ) ;
if ( graphicsWidget - > widgetWebView ( ) - > canBeContent ( ) )
{
graphicsWidget - > widgetWebView ( ) - > loadMainHtml ( ) ;
graphicsWidget - > setSelected ( true ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , graphicsWidget ) ;
UBApplication : : undoStack - > push ( uc ) ;
setDocumentUpdated ( ) ;
}
else
{
UBApplication : : boardController - > moveGraphicsWidgetToControlView ( graphicsWidget ) ;
}
}
UBGraphicsW3CWidgetItem * UBGraphicsScene : : addOEmbed ( const QUrl & pContentUrl , const QPointF & pPos )
{
QStringList widgetPaths = UBPersistenceManager : : persistenceManager ( ) - > allWidgets ( UBSettings : : settings ( ) - > uniboardInteractiveLibraryDirectory ( ) ) ;
UBGraphicsW3CWidgetItem * widget = 0 ;
foreach ( QString widgetPath , widgetPaths )
{
if ( widgetPath . contains ( " VideoPicker " ) )
{
widget = addW3CWidget ( QUrl : : fromLocalFile ( widgetPath ) , pPos ) ;
if ( widget )
{
widget - > setPreference ( " oembedUrl " , pContentUrl . toString ( ) ) ;
setDocumentUpdated ( ) ;
break ;
}
}
}
return widget ;
}
UBGraphicsSvgItem * UBGraphicsScene : : addSvg ( const QUrl & pSvgFileUrl , const QPointF & pPos )
{
QString path = pSvgFileUrl . toLocalFile ( ) ;
UBGraphicsSvgItem * svgItem = new UBGraphicsSvgItem ( path ) ;
svgItem - > setFlag ( QGraphicsItem : : ItemIsMovable , true ) ;
svgItem - > setFlag ( QGraphicsItem : : ItemIsSelectable , true ) ;
svgItem - > setZValue ( getNextObjectZIndex ( ) ) ;
qreal sscale = 1 / UBApplication : : boardController - > systemScaleFactor ( ) ;
svgItem - > scale ( sscale , sscale ) ;
QPointF half ( svgItem - > boundingRect ( ) . width ( ) / 2 , svgItem - > boundingRect ( ) . height ( ) / 2 ) ;
svgItem - > setPos ( pPos - half ) ;
svgItem - > show ( ) ;
addItem ( svgItem ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , svgItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
setDocumentUpdated ( ) ;
return svgItem ;
}
UBGraphicsTextItem * UBGraphicsScene : : addText ( const QString & pString , const QPointF & pTopLeft )
{
return addTextWithFont ( pString , pTopLeft , UBSettings : : settings ( ) - > fontPixelSize ( )
, UBSettings : : settings ( ) - > fontFamily ( ) , UBSettings : : settings ( ) - > isBoldFont ( )
, UBSettings : : settings ( ) - > isItalicFont ( ) ) ;
}
UBGraphicsTextItem * UBGraphicsScene : : addTextWithFont ( const QString & pString , const QPointF & pTopLeft
, int pointSize , const QString & fontFamily , bool bold , bool italic )
{
UBGraphicsTextItem * textItem = new UBGraphicsTextItem ( ) ;
textItem - > setPlainText ( pString ) ;
textItem - > setZValue ( getNextObjectZIndex ( ) ) ;
QFont font ;
if ( fontFamily = = " " )
{
font = QFont ( UBSettings : : settings ( ) - > fontFamily ( ) ) ;
}
else
{
font = QFont ( fontFamily ) ;
}
if ( pointSize < 1 )
{
font . setPixelSize ( UBSettings : : settings ( ) - > fontPixelSize ( ) ) ;
}
else
{
font . setPixelSize ( pointSize ) ;
}
font . setBold ( bold ) ;
font . setItalic ( italic ) ;
textItem - > setFont ( font ) ;
QFontMetrics fi ( font ) ;
QRect br = fi . boundingRect ( pString ) ;
textItem - > setTextWidth ( qMax ( ( qreal ) br . width ( ) + 50 , ( qreal ) 200 ) ) ;
textItem - > setTextHeight ( br . height ( ) ) ;
addItem ( textItem ) ;
textItem - > setPos ( pTopLeft ) ;
textItem - > show ( ) ;
UBGraphicsItemUndoCommand * uc = new UBGraphicsItemUndoCommand ( this , 0 , textItem ) ;
UBApplication : : undoStack - > push ( uc ) ;
connect ( textItem , SIGNAL ( textUndoCommandAdded ( UBGraphicsTextItem * ) ) , this , SLOT ( textUndoCommandAdded ( UBGraphicsTextItem * ) ) ) ;
textItem - > setSelected ( true ) ;
textItem - > setFocus ( ) ;
setDocumentUpdated ( ) ;
return textItem ;
}
void UBGraphicsScene : : addItem ( QGraphicsItem * item )
{
setModified ( true ) ;
UBCoreGraphicsScene : : addItem ( item ) ;
if ( ! mTools . contains ( item ) )
+ + mItemCount ;
mFastAccessItems < < item ;
}
void UBGraphicsScene : : addItems ( const QSet < QGraphicsItem * > & items )
{
setModified ( true ) ;
foreach ( QGraphicsItem * item , items )
UBCoreGraphicsScene : : addItem ( item ) ;
mItemCount + = items . size ( ) ;
mFastAccessItems + = items . toList ( ) ;
}
void UBGraphicsScene : : removeItem ( QGraphicsItem * item )
{
setModified ( true ) ;
UBCoreGraphicsScene : : removeItem ( item ) ;
if ( ! mTools . contains ( item ) )
- - mItemCount ;
mFastAccessItems . removeAll ( item ) ;
}
void UBGraphicsScene : : removeItems ( const QSet < QGraphicsItem * > & items )
{
setModified ( true ) ;
foreach ( QGraphicsItem * item , items )
UBCoreGraphicsScene : : removeItem ( item ) ;
mItemCount - = items . size ( ) ;
foreach ( QGraphicsItem * item , items )
mFastAccessItems . removeAll ( item ) ;
}
void UBGraphicsScene : : deselectAllItems ( )
{
foreach ( QGraphicsItem * gi , selectedItems ( ) )
{
gi - > setSelected ( false ) ;
}
}
bool UBGraphicsScene : : isEmpty ( ) const
{
return mItemCount = = 0 ;
}
QGraphicsItem * UBGraphicsScene : : setAsBackgroundObject ( QGraphicsItem * item , bool pAdaptTransformation , bool pExpand )
{
if ( mBackgroundObject )
{
removeItem ( mBackgroundObject ) ;
mBackgroundObject = 0 ;
}
if ( item )
{
item - > setFlag ( QGraphicsItem : : ItemIsSelectable , false ) ;
item - > setFlag ( QGraphicsItem : : ItemIsMovable , false ) ;
item - > setAcceptedMouseButtons ( Qt : : NoButton ) ;
item - > setData ( UBGraphicsItemData : : ItemLayerType , UBItemLayerType : : FixedBackground ) ;
item - > setZValue ( backgroundLayerStart ) ;
if ( pAdaptTransformation )
{
item = scaleToFitDocumentSize ( item , true , 0 , pExpand ) ;
}
if ( item - > scene ( ) ! = this )
addItem ( item ) ;
mBackgroundObject = item ;
}
return item ;
}
QRectF UBGraphicsScene : : normalizedSceneRect ( qreal ratio )
{
QRectF normalizedRect ( nominalSize ( ) . width ( ) / - 2 , nominalSize ( ) . height ( ) / - 2 ,
nominalSize ( ) . width ( ) , nominalSize ( ) . height ( ) ) ;
foreach ( QGraphicsItem * gi , mFastAccessItems )
{
if ( gi & & gi - > isVisible ( ) & & ! mTools . contains ( gi ) )
{
normalizedRect = normalizedRect . united ( gi - > sceneBoundingRect ( ) ) ;
}
}
if ( ratio > 0.0 )
{
qreal normalizedRectRatio = normalizedRect . width ( ) / normalizedRect . height ( ) ;
if ( normalizedRectRatio > ratio )
{
//the normalized rect is too wide, we increase height
qreal newHeight = normalizedRect . width ( ) / ratio ;
qreal offset = ( newHeight - normalizedRect . height ( ) ) / 2 ;
normalizedRect . setY ( normalizedRect . y ( ) - offset ) ;
normalizedRect . setHeight ( newHeight ) ;
}
else if ( normalizedRectRatio < ratio )
{
//the normalized rect is too high, we increase the width
qreal newWidth = normalizedRect . height ( ) * ratio ;
qreal offset = ( newWidth - normalizedRect . width ( ) ) / 2 ;
normalizedRect . setX ( normalizedRect . x ( ) - offset ) ;
normalizedRect . setWidth ( newWidth ) ;
}
}
return normalizedRect ;
}
void UBGraphicsScene : : setDocument ( UBDocumentProxy * pDocument )
{
if ( pDocument ! = mDocument )
{
if ( mDocument )
{
setModified ( true ) ;
}
mDocument = pDocument ;
setParent ( pDocument ) ;
}
}
QGraphicsItem * UBGraphicsScene : : scaleToFitDocumentSize ( QGraphicsItem * item , bool center , int margin , bool expand )
{
int maxWidth = mNominalSize . width ( ) - ( margin * 2 ) ;
int maxHeight = mNominalSize . height ( ) - ( margin * 2 ) ;
QRectF size = item - > sceneBoundingRect ( ) ;
if ( expand | | size . width ( ) > maxWidth | | size . height ( ) > maxHeight )
{
qreal ratio = qMin ( maxWidth / size . width ( ) , maxHeight / size . height ( ) ) ;
item - > scale ( ratio , ratio ) ;
if ( center )
{
item - > setPos ( item - > sceneBoundingRect ( ) . width ( ) / - 2.0 ,
item - > sceneBoundingRect ( ) . height ( ) / - 2.0 ) ;
}
}
return item ;
}
void UBGraphicsScene : : addRuler ( QPointF center )
{
UBGraphicsRuler * ruler = new UBGraphicsRuler ( ) ; // mem : owned and destroyed by the scene
mTools < < ruler ;
QRectF rect = ruler - > rect ( ) ;
ruler - > setRect ( center . x ( ) - rect . width ( ) / 2 , center . y ( ) - rect . height ( ) / 2 , rect . width ( ) , rect . height ( ) ) ;
ruler - > setZValue ( toolLayerStart + toolOffsetRuler ) ;
ruler - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Tool ) ) ;
addItem ( ruler ) ;
ruler - > setVisible ( true ) ;
setModified ( true ) ;
}
void UBGraphicsScene : : addProtractor ( QPointF center )
{
// Protractor
UBGraphicsProtractor * protractor = new UBGraphicsProtractor ( ) ; // mem : owned and destroyed by the scene
mTools < < protractor ;
protractor - > setZValue ( toolLayerStart + toolOffsetProtractor ) ;
protractor - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Tool ) ) ;
addItem ( protractor ) ;
QPointF itemSceneCenter = protractor - > sceneBoundingRect ( ) . center ( ) ;
protractor - > moveBy ( center . x ( ) - itemSceneCenter . x ( ) , center . y ( ) - itemSceneCenter . y ( ) ) ;
protractor - > setVisible ( true ) ;
setModified ( true ) ;
}
void UBGraphicsScene : : addTriangle ( QPointF center )
{
// Triangle
UBGraphicsTriangle * triangle = new UBGraphicsTriangle ( ) ; // mem : owned and destroyed by the scene
mTools < < triangle ;
triangle - > setZValue ( toolLayerStart + toolOffsetProtractor ) ;
triangle - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Tool ) ) ;
addItem ( triangle ) ;
QPointF itemSceneCenter = triangle - > sceneBoundingRect ( ) . center ( ) ;
triangle - > moveBy ( center . x ( ) - itemSceneCenter . x ( ) , center . y ( ) - itemSceneCenter . y ( ) ) ;
triangle - > setVisible ( true ) ;
setModified ( true ) ;
}
void UBGraphicsScene : : addCompass ( QPointF center )
{
UBGraphicsCompass * compass = new UBGraphicsCompass ( ) ; // mem : owned and destroyed by the scene
mTools < < compass ;
addItem ( compass ) ;
QRectF rect = compass - > rect ( ) ;
compass - > setRect ( center . x ( ) - rect . width ( ) / 2 , center . y ( ) - rect . height ( ) / 2 , rect . width ( ) , rect . height ( ) ) ;
compass - > setZValue ( toolLayerStart + toolOffsetCompass ) ;
compass - > setData ( UBGraphicsItemData : : ItemLayerType , QVariant ( UBItemLayerType : : Tool ) ) ;
compass - > setVisible ( true ) ;
setModified ( true ) ;
}
void UBGraphicsScene : : addMask ( )
{
UBGraphicsCurtainItem * curtain = new UBGraphicsCurtainItem ( ) ; // mem : owned and destroyed by the scene
mTools < < curtain ;
QGraphicsView * view ;
if ( UBApplication : : applicationController - > displayManager ( ) - > hasDisplay ( ) )
view = ( QGraphicsView * ) UBApplication : : boardController - > displayView ( ) ;
else
view = ( QGraphicsView * ) UBApplication : : boardController - > controlView ( ) ;
QPolygonF polygon = view - > mapToScene ( view - > rect ( ) ) ;
curtain - > setZValue ( toolLayerStart + toolOffsetCurtain ) ;
QRectF rect = polygon . boundingRect ( ) ;
qreal xScale = view - > matrix ( ) . m11 ( ) ;
qreal yScale = view - > matrix ( ) . m22 ( ) ;
rect . adjust ( 120 / xScale , 80 / yScale , - 120 / xScale , - 80 / yScale ) ;
curtain - > setRect ( rect ) ;
addItem ( curtain ) ;
curtain - > setVisible ( true ) ;
curtain - > setSelected ( true ) ;
setModified ( true ) ;
}
void UBGraphicsScene : : setRenderingQuality ( UBItem : : RenderingQuality pRenderingQuality )
{
QListIterator < QGraphicsItem * > itItems ( mFastAccessItems ) ;
while ( itItems . hasNext ( ) )
{
QGraphicsItem * gItem = itItems . next ( ) ;
UBItem * ubItem = dynamic_cast < UBItem * > ( gItem ) ;
if ( ubItem )
{
ubItem - > setRenderingQuality ( pRenderingQuality ) ;
}
}
}
QList < QUrl > UBGraphicsScene : : relativeDependencies ( ) const
{
QList < QUrl > relativePathes ;
QListIterator < QGraphicsItem * > itItems ( mFastAccessItems ) ;
while ( itItems . hasNext ( ) )
{
UBGraphicsVideoItem * videoItem = qgraphicsitem_cast < UBGraphicsVideoItem * > ( itItems . next ( ) ) ;
if ( videoItem & & videoItem - > mediaFileUrl ( ) . isRelative ( ) )
{
relativePathes < < videoItem - > mediaFileUrl ( ) ;
}
}
return relativePathes ;
}
QSize UBGraphicsScene : : nominalSize ( )
{
if ( mDocument & & ! mNominalSize . isValid ( ) )
{
mNominalSize = mDocument - > defaultDocumentSize ( ) ;
}
return mNominalSize ;
}
void UBGraphicsScene : : setNominalSize ( const QSize & pSize )
{
if ( nominalSize ( ) ! = pSize )
{
mNominalSize = pSize ;
emit pageSizeChanged ( ) ;
if ( mDocument )
mDocument - > setDefaultDocumentSize ( pSize ) ;
}
}
void UBGraphicsScene : : setNominalSize ( int pWidth , int pHeight )
{
setNominalSize ( QSize ( pWidth , pHeight ) ) ;
}
QGraphicsItem * UBGraphicsScene : : rootItem ( QGraphicsItem * item ) const
{
QGraphicsItem * root = item ;
while ( root - > parentItem ( ) )
{
root = root - > parentItem ( ) ;
}
return root ;
}
void UBGraphicsScene : : drawItems ( QPainter * painter , int numItems ,
QGraphicsItem * items [ ] , const QStyleOptionGraphicsItem options [ ] , QWidget * widget )
{
if ( mRenderingContext = = NonScreen | | mRenderingContext = = PdfExport )
{
int count = 0 ;
QGraphicsItem * * itemsFiltered = new QGraphicsItem * [ numItems ] ;
QStyleOptionGraphicsItem * optionsFiltered = new QStyleOptionGraphicsItem [ numItems ] ;
for ( int i = 0 ; i < numItems ; i + + )
{
if ( ! mTools . contains ( rootItem ( items [ i ] ) ) )
{
UBGraphicsPDFItem * pdfItem = qgraphicsitem_cast < UBGraphicsPDFItem * > ( items [ i ] ) ;
if ( ! pdfItem | | mRenderingContext = = NonScreen )
{
itemsFiltered [ count ] = items [ i ] ;
optionsFiltered [ count ] = options [ i ] ;
count + + ;
}
}
}
QGraphicsScene : : drawItems ( painter , count , itemsFiltered , optionsFiltered , widget ) ;
delete [ ] optionsFiltered ;
delete [ ] itemsFiltered ;
}
else if ( mRenderingContext = = Podcast )
{
int count = 0 ;
QGraphicsItem * * itemsFiltered = new QGraphicsItem * [ numItems ] ;
QStyleOptionGraphicsItem * optionsFiltered = new QStyleOptionGraphicsItem [ numItems ] ;
for ( int i = 0 ; i < numItems ; i + + )
{
bool ok ;
int itemLayerType = items [ i ] - > data ( UBGraphicsItemData : : ItemLayerType ) . toInt ( & ok ) ;
if ( ok & & ( itemLayerType > = UBItemLayerType : : FixedBackground & & itemLayerType < = UBItemLayerType : : Tool ) )
{
itemsFiltered [ count ] = items [ i ] ;
optionsFiltered [ count ] = options [ i ] ;
count + + ;
}
}
QGraphicsScene : : drawItems ( painter , count , itemsFiltered , optionsFiltered , widget ) ;
delete [ ] optionsFiltered ;
delete [ ] itemsFiltered ;
}
else
{
QGraphicsScene : : drawItems ( painter , numItems , items , options , widget ) ;
}
}
void UBGraphicsScene : : keyReleaseEvent ( QKeyEvent * keyEvent )
{
QList < QGraphicsItem * > si = selectedItems ( ) ;
if ( si . size ( ) > 0 & & ! keyEvent - > isAccepted ( ) )
{
# ifdef Q_OS_MAC
if ( keyEvent - > key ( ) = = Qt : : Key_Backspace )
# else
if ( keyEvent - > matches ( QKeySequence : : Delete ) )
# endif
{
foreach ( QGraphicsItem * item , si )
{
UBGraphicsItem * ubgi = dynamic_cast < UBGraphicsItem * > ( item ) ;
if ( ubgi )
{
ubgi - > remove ( ) ;
}
}
}
keyEvent - > accept ( ) ;
}
QGraphicsScene : : keyReleaseEvent ( keyEvent ) ;
}
void UBGraphicsScene : : setDocumentUpdated ( )
{
if ( document ( ) )
document ( ) - > setMetaData ( UBSettings : : documentUpdatedAt
, UBStringUtils : : toUtcIsoDateTime ( QDateTime : : currentDateTime ( ) ) ) ;
}
void UBGraphicsScene : : setToolCursor ( int tool )
{
if ( tool ! = ( int ) UBStylusTool : : Selector
& & tool ! = ( int ) UBStylusTool : : Text )
{
deselectAllItems ( ) ;
}
if ( tool ! = ( int ) UBStylusTool : : Eraser )
{
hideEraser ( ) ;
}
}