@ -65,6 +65,9 @@
# include "core/memcheck.h"
# include "core/memcheck.h"
const QString groupText = " Group items " ;
const QString ungroupText = " Ungroup items " ;
qreal UBZLayerController : : errorNumber = - 20000001.0 ;
qreal UBZLayerController : : errorNumber = - 20000001.0 ;
UBZLayerController : : UBZLayerController ( QGraphicsScene * scene ) :
UBZLayerController : : UBZLayerController ( QGraphicsScene * scene ) :
@ -291,9 +294,15 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent)
}
}
connect ( this , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( selectionChangedProcessing ( ) ) ) ;
connect ( this , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( selectionChangedProcessing ( ) ) ) ;
connect ( this , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( enableGroupingButton ( ) ) ) ;
connect ( this , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( updateGroupButtonState ( ) ) ) ;
connect ( UBApplication : : mainWindow - > actionGroupItems , SIGNAL ( triggered ( ) ) , this , SLOT ( processGroupItems ( ) ) ) ;
// just a stub don't treat as a result code
// static int i = 0;
// i++;
// if (i == 1) {
connect ( UBApplication : : mainWindow - > actionGroupItems , SIGNAL ( triggered ( ) ) , this , SLOT ( groupButtonClicked ( ) ) ) ;
// qDebug() << "the connect is accepted";
// }
}
}
UBGraphicsScene : : ~ UBGraphicsScene ( )
UBGraphicsScene : : ~ UBGraphicsScene ( )
@ -308,39 +317,78 @@ UBGraphicsScene::~UBGraphicsScene()
void UBGraphicsScene : : selectionChangedProcessing ( )
void UBGraphicsScene : : selectionChangedProcessing ( )
{
{
if ( selectedItems ( ) . count ( ) )
if ( selectedItems ( ) . count ( ) ) {
qDebug ( ) < < " Selected item bounding rect: " < < selectedItems ( ) . first ( ) - > boundingRect ( ) ;
UBApplication : : showMessage ( " ZValue is " + QString : : number ( selectedItems ( ) . first ( ) - > zValue ( ) , ' f ' ) + " own z value is "
UBApplication : : showMessage ( " ZValue is " + QString : : number ( selectedItems ( ) . first ( ) - > zValue ( ) , ' f ' ) + " own z value is "
+ QString : : number ( selectedItems ( ) . first ( ) - > data ( UBGraphicsItemData : : ItemOwnZValue ) . toReal ( ) , ' f ' ) ) ;
+ QString : : number ( selectedItems ( ) . first ( ) - > data ( UBGraphicsItemData : : ItemOwnZValue ) . toReal ( ) , ' f ' ) ) ;
}
}
void UBGraphicsScene : : enableGroupingButton ( )
}
void UBGraphicsScene : : updateGroupButtonState ( )
{
{
QAction * groupAction = UBApplication : : mainWindow - > actionGroupItems ;
QAction * groupAction = UBApplication : : mainWindow - > actionGroupItems ;
QList < QGraphicsItem * > selItems = selectedItems ( ) ;
int selCount = selItems . count ( ) ;
if ( selectedItems ( ) . count ( ) > 1 ) {
if ( selCount < 1 ) {
groupAction - > setEnabled ( false ) ;
groupAction - > setText ( groupText ) ;
} else if ( selCount = = 1 ) {
if ( selItems . first ( ) - > type ( ) = = UBGraphicsGroupContainerItem : : Type ) {
groupAction - > setEnabled ( true ) ;
groupAction - > setEnabled ( true ) ;
groupAction - > setText ( ungroupText ) ;
} else {
} else {
groupAction - > setEnabled ( false ) ;
groupAction - > setEnabled ( false ) ;
}
}
} else if ( selCount > 1 ) {
groupAction - > setEnabled ( true ) ;
groupAction - > setText ( groupText ) ;
}
}
}
void UBGraphicsScene : : processGroupItems ( )
void UBGraphicsScene : : groupButtonClicked ( )
{
{
qDebug ( ) < < " processing grouping items " ;
QAction * groupAction = UBApplication : : mainWindow - > actionGroupItems ;
QList < QGraphicsItem * > selItems = selectedItems ( ) ;
if ( ! selItems . count ( ) ) {
qDebug ( ) < < " Got grouping request when there is no any selected item on the scene " ;
return ;
}
if ( groupAction - > text ( ) = = groupText ) { //The only way to get information from item, considering using smth else
UBGraphicsGroupContainerItem * groupItem = new UBGraphicsGroupContainerItem ( ) ;
UBGraphicsGroupContainerItem * groupItem = new UBGraphicsGroupContainerItem ( ) ;
foreach ( QGraphicsItem * item , selectedItems ( ) ) {
foreach ( QGraphicsItem * item , selItems ) {
item - > setSelected ( false ) ;
if ( item - > type ( ) = = UBGraphicsGroupContainerItem : : Type ) {
item - > setFlag ( QGraphicsItem : : ItemIsSelectable , false ) ;
QList < QGraphicsItem * > childItems = item - > childItems ( ) ;
item - > setFlag ( QGraphicsItem : : ItemIsMovable , false ) ;
UBGraphicsGroupContainerItem * currentGroup = dynamic_cast < UBGraphicsGroupContainerItem * > ( item ) ;
item - > setFlag ( QGraphicsItem : : ItemIsFocusable ) ;
if ( currentGroup ) {
currentGroup - > destroy ( ) ;
}
foreach ( QGraphicsItem * chItem , childItems ) {
groupItem - > addToGroup ( chItem ) ;
}
} else {
groupItem - > addToGroup ( item ) ;
groupItem - > addToGroup ( item ) ;
}
}
}
addItem ( groupItem ) ;
addItem ( groupItem ) ;
// groupItem->setPos(50, 50);
groupItem - > setVisible ( true ) ;
groupItem - > setVisible ( true ) ;
groupItem - > setFocus ( ) ;
groupItem - > setFocus ( ) ;
qDebug ( ) < < groupItem - > boundingRect ( ) ;
} else if ( groupAction - > text ( ) = = ungroupText ) {
//Considering one selected item and it's a group
if ( selItems . count ( ) > 1 ) {
qDebug ( ) < < " can't make sense of ungrouping more then one item. Grouping action should be performed for that purpose " ;
return ;
}
UBGraphicsGroupContainerItem * currentGroup = dynamic_cast < UBGraphicsGroupContainerItem * > ( selItems . first ( ) ) ;
if ( currentGroup ) {
currentGroup - > destroy ( ) ;
}
}
}
}
// MARK: -
// MARK: -
@ -432,7 +480,6 @@ bool UBGraphicsScene::inputDevicePress(const QPointF& scenePos, const qreal& pre
return accepted ;
return accepted ;
}
}
bool UBGraphicsScene : : inputDeviceMove ( const QPointF & scenePos , const qreal & pressure )
bool UBGraphicsScene : : inputDeviceMove ( const QPointF & scenePos , const qreal & pressure )
{
{
bool accepted = false ;
bool accepted = false ;
@ -567,7 +614,7 @@ bool UBGraphicsScene::inputDeviceRelease()
}
}
} else if ( mCurrentStroke )
} else if ( mCurrentStroke )
{
{
if ( eDrawingMode_Vector = = dc - > drawingMode ( ) ) {
if ( eDrawingMode_Vector = = DRAWING_MODE ) {
UBGraphicsStrokesGroup * pStrokes = new UBGraphicsStrokesGroup ( ) ;
UBGraphicsStrokesGroup * pStrokes = new UBGraphicsStrokesGroup ( ) ;
// Remove the strokes that were just drawn here and replace them by a stroke item
// Remove the strokes that were just drawn here and replace them by a stroke item
@ -575,6 +622,7 @@ bool UBGraphicsScene::inputDeviceRelease()
mPreviousPolygonItems . removeAll ( poly ) ;
mPreviousPolygonItems . removeAll ( poly ) ;
removeItem ( poly ) ;
removeItem ( poly ) ;
UBCoreGraphicsScene : : removeItemFromDeletion ( poly ) ;
UBCoreGraphicsScene : : removeItemFromDeletion ( poly ) ;
poly - > setStrokesGroup ( pStrokes ) ;
pStrokes - > addToGroup ( poly ) ;
pStrokes - > addToGroup ( poly ) ;
}
}
@ -746,6 +794,8 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &pWidth,
void UBGraphicsScene : : eraseLineTo ( const QPointF & pEndPoint , const qreal & pWidth )
void UBGraphicsScene : : eraseLineTo ( const QPointF & pEndPoint , const qreal & pWidth )
{
{
// QList<QGraphicsItem*> itemList;
const QLineF line ( mPreviousPoint , pEndPoint ) ;
const QLineF line ( mPreviousPoint , pEndPoint ) ;
const QPolygonF eraserPolygon = UBGeometryUtils : : lineToPolygon ( line , pWidth ) ;
const QPolygonF eraserPolygon = UBGeometryUtils : : lineToPolygon ( line , pWidth ) ;
@ -756,58 +806,107 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
eraserPathVar . addPolygon ( eraserPolygon ) ;
eraserPathVar . addPolygon ( eraserPolygon ) ;
const QPainterPath eraserPath = eraserPathVar ;
const QPainterPath eraserPath = eraserPathVar ;
// Get all the items that are intersecting with the eraser path
QList < QGraphicsItem * > collidItems = items ( eraserBoundingRect , Qt : : IntersectsItemBoundingRect ) ;
QList < QGraphicsItem * > collidItems = items ( eraserBoundingRect , Qt : : IntersectsItemBoundingRect ) ;
if ( eDrawingMode_Vector = = UBDrawingController : : drawingController ( ) - > drawingMode ( ) ) {
// NOTE: I decided to reuse the 'artistic' eraser all the time in order to have a better eraser
// For this reason, the following code is not used but we will keep it for now, in case of
// futur requirements.
foreach ( QGraphicsItem * poly , collidItems ) {
UBGraphicsStrokesGroup * pGroup = dynamic_cast < UBGraphicsStrokesGroup * > ( poly ) ;
if ( NULL ! = pGroup ) {
// TODO: Ungroup the item, put back the polygons on the scene, deal with the
// eraser's bounding rect, remove the polygons that must be removed
// then create new groups.
// Get all substrokes and verify if they are part of the eraserpath then deal with it
foreach ( QGraphicsItem * item , poly - > childItems ( ) ) {
UBGraphicsPolygonItem * polygon = dynamic_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( NULL ! = polygon ) {
if ( eraserBoundingRect . intersects ( polygon - > boundingRect ( ) ) ) {
pGroup - > removeFromGroup ( polygon ) ;
removeItem ( polygon ) ;
}
}
}
}
}
} else {
QSet < QGraphicsItem * > toBeAddedItems ;
QSet < QGraphicsItem * > toBeAddedItems ;
QSet < QGraphicsItem * > toBeRemovedItems ;
QSet < QGraphicsItem * > toBeRemovedItems ;
int collidItemsSize = collidItems . size ( ) ;
int collidItemsSize = collidItems . size ( ) ;
toBeAddedItems . reserve ( collidItemsSize ) ;
toBeAddedItems . reserve ( collidItemsSize ) ;
toBeRemovedItems . reserve ( collidItemsSize ) ;
toBeRemovedItems . reserve ( collidItemsSize ) ;
if ( mShouldUseOMP )
if ( mShouldUseOMP )
{
{
# pragma omp parallel for
// #pragma omp parallel for
for ( int i = 0 ; i < collidItemsSize ; i + + )
for ( int i = 0 ; i < collidItemsSize ; i + + )
{
{
UBGraphicsPolygonItem * collidingPolygonItem
UBGraphicsPolygonItem * collidingPolygonItem = qgraphicsitem_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
= qgraphicsitem_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
if ( collidingPolygonItem )
if ( NULL ! = collidingPolygonItem )
{
{
collidingPolygonItem - > setColor ( QColor ( Qt : : green ) ) ;
UBGraphicsStrokesGroup * pGroup = collidingPolygonItem - > strokesGroup ( ) ;
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
{
{
# pragma omp critical
// #pragma omp critical
qDebug ( ) < < " case 1 " ;
// Put the entire polygon into the remove list
collidingPolygonItem - > setColor ( QColor ( Qt : : blue ) ) ;
toBeRemovedItems < < collidingPolygonItem ;
toBeRemovedItems < < collidingPolygonItem ;
}
}
else
else
{
{
// Here we get the polygon of the colliding item
QPolygonF collidingPolygon = collidingPolygonItem - > polygon ( ) ;
QPolygonF collidingPolygon = collidingPolygonItem - > polygon ( ) ;
QPainterPath collidingPath ;
QPainterPath collidingPath ;
collidingPath . addPolygon ( collidingPolygon ) ;
collidingPath . addPolygon ( collidingPolygon ) ;
// Then we substract the eraser path to the polygon and we simplify it
QPainterPath croppedPath = collidingPath . subtracted ( eraserPath ) ;
QPainterPath croppedPath = collidingPath . subtracted ( eraserPath ) ;
QPainterPath croppedPathSimplified = croppedPath . simplified ( ) ;
QPainterPath croppedPathSimplified = croppedPath . simplified ( ) ;
if ( croppedPath = = collidingPath )
/*if (croppedPath == collidingPath)
{
{
// NOOP
// NOOP
qDebug ( ) < < " case 2 " ;
toBeRemovedItems < < collidingPolygonItem ;
}
}
else if ( croppedPathSimplified . isEmpty ( ) )
else */ if ( croppedPathSimplified . isEmpty ( ) )
{
{
# pragma omp critical
// #pragma omp critical
qDebug ( ) < < " case 3 " ;
// Put the entire polygon into the remove list if the eraser removes all its visible content
collidingPolygonItem - > setColor ( QColor ( Qt : : blue ) ) ;
toBeRemovedItems < < collidingPolygonItem ;
toBeRemovedItems < < collidingPolygonItem ;
}
}
else
else
{
{
//qDebug() << "case 4";
// Then we convert the remaining path to a list of polygons that will be converted in
// UBGraphicsPolygonItems and added to the scene
foreach ( const QPolygonF & pol , croppedPathSimplified . toFillPolygons ( ) )
foreach ( const QPolygonF & pol , croppedPathSimplified . toFillPolygons ( ) )
{
{
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
# pragma omp critical
croppedPolygonItem - > setColor ( QColor ( Qt : : black ) ) ;
// #pragma omp critical
if ( NULL ! = pGroup ) {
croppedPolygonItem - > setStrokesGroup ( pGroup ) ;
// croppedPolygonItem->setTransform(pGroup->sceneTransform().inverted());
}
// Add this new polygon to the 'added' list
toBeAddedItems < < croppedPolygonItem ;
toBeAddedItems < < croppedPolygonItem ;
}
}
# pragma omp critical
// #pragma omp critical
// Remove the original polygonitem because it has been replaced by many smaller polygons
collidingPolygonItem - > setColor ( QColor ( Qt : : blue ) ) ;
toBeRemovedItems < < collidingPolygonItem ;
toBeRemovedItems < < collidingPolygonItem ;
}
}
}
}
@ -818,11 +917,12 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
{
{
for ( int i = 0 ; i < collidItemsSize ; i + + )
for ( int i = 0 ; i < collidItemsSize ; i + + )
{
{
UBGraphicsPolygonItem * collidingPolygonItem
UBGraphicsPolygonItem * collidingPolygonItem = dynamic_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
= qgraphicsitem_cast < UBGraphicsPolygonItem * > ( collidItems . at ( i ) ) ;
if ( collidingPolygonItem )
if ( collidingPolygonItem )
{
{
UBGraphicsStrokesGroup * pGroup = collidingPolygonItem - > strokesGroup ( ) ;
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
if ( eraserInnerRect . contains ( collidingPolygonItem - > boundingRect ( ) ) )
{
{
toBeRemovedItems < < collidingPolygonItem ;
toBeRemovedItems < < collidingPolygonItem ;
@ -850,6 +950,9 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
{
{
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
UBGraphicsPolygonItem * croppedPolygonItem = collidingPolygonItem - > deepCopy ( pol ) ;
toBeAddedItems < < croppedPolygonItem ;
toBeAddedItems < < croppedPolygonItem ;
if ( NULL ! = pGroup ) {
croppedPolygonItem - > setStrokesGroup ( pGroup ) ;
}
}
}
toBeRemovedItems < < collidingPolygonItem ;
toBeRemovedItems < < collidingPolygonItem ;
@ -859,11 +962,52 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
}
}
}
}
addItems ( toBeAddedItems ) ;
if ( eDrawingMode_Vector = = DRAWING_MODE ) {
mAddedItems + = toBeAddedItems ;
foreach ( QGraphicsItem * item , toBeRemovedItems ) {
UBGraphicsPolygonItem * poly = dynamic_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( NULL ! = poly ) {
if ( NULL ! = poly - > strokesGroup ( ) ) {
poly - > strokesGroup ( ) - > removeFromGroup ( poly ) ;
removeItem ( poly ) ;
} else {
qDebug ( ) < < " No group present " ;
}
}
}
} else {
removeItems ( toBeRemovedItems ) ;
removeItems ( toBeRemovedItems ) ;
mRemovedItems + = toBeRemovedItems ;
mRemovedItems + = toBeRemovedItems ;
}
// bool hack = false;
// UBGraphicsStrokesGroup* pG = new UBGraphicsStrokesGroup();
if ( eDrawingMode_Vector = = DRAWING_MODE ) {
foreach ( QGraphicsItem * item , toBeAddedItems ) {
UBGraphicsPolygonItem * poly = dynamic_cast < UBGraphicsPolygonItem * > ( item ) ;
if ( NULL ! = poly & & NULL ! = poly - > strokesGroup ( ) ) {
// if(!hack){
// itemList = poly->strokesGroup()->childItems();
// removeItem(poly->strokesGroup());
// foreach(QGraphicsItem* it, itemList){
// pG->addToGroup(it);
// }
// hack = true;
// }
qreal dx = - poly - > strokesGroup ( ) - > sceneTransform ( ) . inverted ( ) . dx ( ) ;
qreal dy = - poly - > strokesGroup ( ) - > sceneTransform ( ) . inverted ( ) . dy ( ) ;
//poly->setTransform(QTransform().translate(20, 0));
poly - > setTransform ( QTransform ( ) . translate ( dx , dy ) ) ;
poly - > strokesGroup ( ) /*pG*/ - > addToGroup ( poly ) ;
}
}
//addItem(pG);
} else {
addItems ( toBeAddedItems ) ;
mAddedItems + = toBeAddedItems ;
}
}
mPreviousPoint = pEndPoint ;
mPreviousPoint = pEndPoint ;
}
}
@ -1759,7 +1903,6 @@ QGraphicsItem* UBGraphicsScene::scaleToFitDocumentSize(QGraphicsItem* item, bool
return item ;
return item ;
}
}
void UBGraphicsScene : : addRuler ( QPointF center )
void UBGraphicsScene : : addRuler ( QPointF center )
{
{
UBGraphicsRuler * ruler = new UBGraphicsRuler ( ) ; // mem : owned and destroyed by the scene
UBGraphicsRuler * ruler = new UBGraphicsRuler ( ) ; // mem : owned and destroyed by the scene