Skip to content
Permalink
Browse files

Possibility to lock/unlock composer item position by right mouse click

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10775 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent
mhugent committed May 12, 2009
1 parent 01b6b9a commit 7db0a84c98f6d68b501ff8ac4c5c603583962839
Binary file not shown.
@@ -16,20 +16,25 @@
***************************************************************************/
#include <QWidget>
#include <QDomNode>
#include <QFile>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QPainter>

#include "qgscomposition.h"
#include "qgscomposeritem.h"


#include <limits>
#include "qgsapplication.h"
#include "qgsrectangle.h" //just for debugging
#include "qgslogger.h"

#define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter

QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue ): QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true )
QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue ): QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), \
mFrame( true ), mItemPositionLocked(false)
{
setFlag( QGraphicsItem::ItemIsSelectable, true );
setAcceptsHoverEvents( true );
@@ -119,6 +124,17 @@ bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) cons
composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
composerItemElem.setAttribute( "outlineWidth", QString::number( pen().widthF() ) );

//position lock for mouse moves/resizes
if(mItemPositionLocked)
{
composerItemElem.setAttribute( "positionLock", "true");
}
else
{
composerItemElem.setAttribute( "positionLock", "false");
}


//frame color
QDomElement frameColorElem = doc.createElement( "FrameColor" );
QColor frameColor = pen().color();
@@ -160,6 +176,17 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument&
mFrame = false;
}

//position lock for mouse moves/resizes
QString positionLock = itemElem.attribute("positionLock");
if(positionLock.compare("true", Qt::CaseInsensitive) == 0)
{
mItemPositionLocked = true;
}
else
{
mItemPositionLocked = false;
}

//position
double x, y, width, height;
bool xOk, yOk, widthOk, heightOk;
@@ -219,7 +246,11 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument&

void QgsComposerItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
{
qWarning( "QgsComposerItem::mouseMoveEvent" );
if(mItemPositionLocked)
{
return;
}

if ( mBoundingResizeRectangle )
{
double diffX = event->lastScenePos().x() - mLastMouseEventPos.x();
@@ -232,6 +263,11 @@ void QgsComposerItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )

void QgsComposerItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
{
if(mItemPositionLocked)
{
return;
}

//set current position and type of mouse move action
mMouseMoveStartPos = event->lastScenePos();
mLastMouseEventPos = event->lastScenePos();
@@ -260,6 +296,12 @@ void QgsComposerItem::mousePressEvent( QGraphicsSceneMouseEvent * event )

void QgsComposerItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event )
{

if(mItemPositionLocked)
{
return;
}

//delete frame rectangle
if ( mBoundingResizeRectangle )
{
@@ -289,6 +331,10 @@ Qt::CursorShape QgsComposerItem::cursorForPosition( const QPointF& itemCoordPos
{
QgsComposerItem::MouseMoveAction mouseAction = mouseMoveActionForPosition( itemCoordPos );

if( mouseAction == QgsComposerItem::NoAction)
{
return Qt::ForbiddenCursor;
}
if ( mouseAction == QgsComposerItem::MoveItem )
{
return Qt::ClosedHandCursor;
@@ -314,8 +360,11 @@ Qt::CursorShape QgsComposerItem::cursorForPosition( const QPointF& itemCoordPos
QgsComposerItem::MouseMoveAction QgsComposerItem::mouseMoveActionForPosition( const QPointF& itemCoordPos )
{

//move content tool

//no action at all if item position is locked for mouse
if(mItemPositionLocked)
{
return QgsComposerItem::NoAction;
}

bool nearLeftBorder = false;
bool nearRightBorder = false;
@@ -472,15 +521,53 @@ void QgsComposerItem::drawSelectionBoxes( QPainter* p )

if ( mComposition->plotStyle() == QgsComposition::Preview )
{
p->setPen( QPen( QColor( 0, 0, 255 ) ) );
p->setBrush( QBrush( QColor( 0, 0, 255 ) ) );
//size of symbol boxes depends on zoom level in composer view
double viewScaleFactor = horizontalViewScaleFactor();
double rectHandlerSize = 10.0 / viewScaleFactor;
double lockSymbolSize = 20.0 / viewScaleFactor;

double s = 5;
//make sure the boxes don't get too large
if(rectHandlerSize > (rect().width() / 3))
{
rectHandlerSize = rect().width() / 3;
}
if(rectHandlerSize > (rect().height() / 3))
{
rectHandlerSize = rect().height() / 3;
}
if(lockSymbolSize > (rect().width() / 3))
{
lockSymbolSize = rect().width() / 3;
}
if(lockSymbolSize > (rect().height() / 3))
{
lockSymbolSize = rect().height() / 3;
}

p->drawRect( QRectF( 0, 0, s, s ) );
p->drawRect( QRectF( rect().width() - s, 0, s, s ) );
p->drawRect( QRectF( rect().width() - s, rect().height() - s, s, s ) );
p->drawRect( QRectF( 0, rect().height() - s, s, s ) );
if(mItemPositionLocked)
{
//draw lock symbol at upper left edge. Use QImage to be independant of the graphic system
QString lockIconPath = QgsApplication::activeThemePath() + "/mIconLock.png";
if(!QFile::exists(lockIconPath))
{
lockIconPath = QgsApplication::defaultThemePath() + "/mIconLock.png";
}

QImage lockImage(lockIconPath);
if(!lockImage.isNull())
{
p->drawImage(QRectF(0, 0, lockSymbolSize, lockSymbolSize), lockImage, QRectF(0, 0, lockImage.width(), lockImage.height()));
}
}
else //draw blue squares
{
p->setPen( QPen( QColor( 0, 0, 255 ) ) );
p->setBrush( QBrush( QColor( 0, 0, 255 ) ) );
p->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
p->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
p->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
p->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
}
}
}

@@ -637,3 +724,26 @@ QFont QgsComposerItem::scaledFontPixelSize( const QFont& font ) const
scaledFont.setPixelSize( pixelSize );
return scaledFont;
}

double QgsComposerItem::horizontalViewScaleFactor() const
{
double result = 1;
if ( scene() )
{
QList<QGraphicsView*> viewList = scene()->views();
if ( viewList.size() > 0 )
{
result = viewList.at( 0 )->transform().m11();
}
else
{
return 1; //probably called from non-gui code
}
}
return result;
}

void QgsComposerItem::updateCursor(const QPointF& itemPos)
{
setCursor( cursorForPosition(itemPos) );
}
@@ -45,7 +45,8 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
ResizeLeftUp,
ResizeRightUp,
ResizeLeftDown,
ResizeRightDown
ResizeRightDown,
NoAction
};

enum ItemPositionMode
@@ -155,6 +156,18 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
/**Returns a font where size is in pixel and font size is upscaled with FONT_WORKAROUND_SCALE*/
QFont scaledFontPixelSize( const QFont& font ) const;

/**Locks / unlocks the item position for mouse drags
@note this method was added in version 1.2*/
void setPositionLock(bool lock){mItemPositionLocked = lock;}

/**Returns position lock for mouse drags (true means locked)
@note this method was added in version 1.2*/
bool positionLock() const {return mItemPositionLocked;}

/**Update mouse cursor at (item) position
@note this method was added in version 1.2*/
void updateCursor(const QPointF& itemPos);

protected:

QgsComposition* mComposition;
@@ -171,6 +184,10 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
/**True if item fram needs to be painted*/
bool mFrame;

/**True if item position and size cannot be changed with mouse move
@note: this member was added in version 1.2*/
bool mItemPositionLocked;

//event handlers
virtual void mouseMoveEvent( QGraphicsSceneMouseEvent * event );
virtual void mousePressEvent( QGraphicsSceneMouseEvent * event );
@@ -202,6 +219,10 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem

/**Draw background*/
virtual void drawBackground( QPainter* p );

/**Returns the zoom factor of the graphics view. If no
graphics view exists, the default 1 is returned*/
double horizontalViewScaleFactor() const;
};

#endif
@@ -34,7 +34,6 @@
#include "qgslabelattributes.h"

#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPainter>
#include <QSettings>
#include <iostream>
@@ -457,24 +456,6 @@ bool QgsComposerMap::containsWMSLayer() const
return false;
}

double QgsComposerMap::horizontalViewScaleFactor() const
{
double result = 1;
if ( scene() )
{
QList<QGraphicsView*> viewList = scene()->views();
if ( viewList.size() > 0 )
{
result = viewList.at( 0 )->transform().m11();
}
else
{
return 1; //probably called from non-gui code
}
}
return result;
}

void QgsComposerMap::connectUpdateSlot()
{
//connect signal from layer registry to update in case of new or deleted layers
@@ -185,10 +185,6 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB

/**Establishes signal/slot connection for update in case of layer change*/
void connectUpdateSlot();

/**Returns the zoom factor of the graphics view. If no
graphics view exists, the default 1 is returned*/
double horizontalViewScaleFactor() const;
};

#endif
@@ -45,6 +45,22 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
QPointF scenePoint = mapToScene( e->pos() );
QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );

//lock/unlock position of item with right click
if(e->button() == Qt::RightButton)
{
QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint );
if(selectedItem)
{
bool lock = selectedItem->positionLock() ? false : true;
selectedItem->setPositionLock(lock);
selectedItem->update();
//make sure the new cursor is correct
QPointF itemPoint = selectedItem->mapFromScene( scenePoint );
selectedItem->updateCursor(itemPoint);
}
return;
}

switch ( mCurrentTool )
{
//select/deselect items and pass mouse event further

0 comments on commit 7db0a84

Please sign in to comment.
You can’t perform that action at this time.