mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-08 00:38:10 -05:00
Show guide positions in rulers
This commit is contained in:
parent
ab726c4777
commit
c6c9c6fabf
@ -181,10 +181,11 @@ class QgsLayoutGuideCollection : QAbstractTableModel
|
|||||||
Updates the position (and visibility) of all guide line items.
|
Updates the position (and visibility) of all guide line items.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
QList< QgsLayoutGuide * > guides( QgsLayoutGuide::Orientation orientation );
|
QList< QgsLayoutGuide * > guides( QgsLayoutGuide::Orientation orientation, int page = -1 );
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the list of guides contained in the collection with the specified
|
Returns the list of guides contained in the collection with the specified
|
||||||
``orientation``.
|
``orientation`` and on a matching ``page``.
|
||||||
|
If ``page`` is -1, guides from all pages will be returned.
|
||||||
:rtype: list of QgsLayoutGuide
|
:rtype: list of QgsLayoutGuide
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
|||||||
@ -117,10 +117,10 @@ double QgsLayoutGuide::layoutPosition() const
|
|||||||
switch ( mOrientation )
|
switch ( mOrientation )
|
||||||
{
|
{
|
||||||
case Horizontal:
|
case Horizontal:
|
||||||
return mLineItem->line().y1();
|
return mLineItem->mapToScene( mLineItem->line().p1() ).y();
|
||||||
|
|
||||||
case Vertical:
|
case Vertical:
|
||||||
return mLineItem->line().x1();
|
return mLineItem->mapToScene( mLineItem->line().p1() ).x();
|
||||||
}
|
}
|
||||||
return -999; // avoid warning
|
return -999; // avoid warning
|
||||||
}
|
}
|
||||||
@ -237,6 +237,7 @@ bool QgsLayoutGuideCollection::setData( const QModelIndex &index, const QVariant
|
|||||||
m.setLength( newPos );
|
m.setLength( newPos );
|
||||||
whileBlocking( guide )->setPosition( m );
|
whileBlocking( guide )->setPosition( m );
|
||||||
guide->update();
|
guide->update();
|
||||||
|
emit dataChanged( index, index, QVector<int>() << role );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case PositionRole:
|
case PositionRole:
|
||||||
@ -250,6 +251,7 @@ bool QgsLayoutGuideCollection::setData( const QModelIndex &index, const QVariant
|
|||||||
m.setLength( newPos );
|
m.setLength( newPos );
|
||||||
whileBlocking( guide )->setPosition( m );
|
whileBlocking( guide )->setPosition( m );
|
||||||
guide->update();
|
guide->update();
|
||||||
|
emit dataChanged( index, index, QVector<int>() << role );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case UnitsRole:
|
case UnitsRole:
|
||||||
@ -263,6 +265,7 @@ bool QgsLayoutGuideCollection::setData( const QModelIndex &index, const QVariant
|
|||||||
m.setUnits( static_cast< QgsUnitTypes::LayoutUnit >( units ) );
|
m.setUnits( static_cast< QgsUnitTypes::LayoutUnit >( units ) );
|
||||||
whileBlocking( guide )->setPosition( m );
|
whileBlocking( guide )->setPosition( m );
|
||||||
guide->update();
|
guide->update();
|
||||||
|
emit dataChanged( index, index, QVector<int>() << role );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,12 +328,13 @@ void QgsLayoutGuideCollection::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QgsLayoutGuide *> QgsLayoutGuideCollection::guides( QgsLayoutGuide::Orientation orientation )
|
QList<QgsLayoutGuide *> QgsLayoutGuideCollection::guides( QgsLayoutGuide::Orientation orientation, int page )
|
||||||
{
|
{
|
||||||
QList<QgsLayoutGuide *> res;
|
QList<QgsLayoutGuide *> res;
|
||||||
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
|
Q_FOREACH ( QgsLayoutGuide *guide, mGuides )
|
||||||
{
|
{
|
||||||
if ( guide->orientation() == orientation && guide->item()->isVisible() )
|
if ( guide->orientation() == orientation && guide->item()->isVisible() &&
|
||||||
|
( page < 0 || page == guide->page() ) )
|
||||||
res << guide;
|
res << guide;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@ -207,9 +207,10 @@ class CORE_EXPORT QgsLayoutGuideCollection : public QAbstractTableModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of guides contained in the collection with the specified
|
* Returns the list of guides contained in the collection with the specified
|
||||||
* \a orientation.
|
* \a orientation and on a matching \a page.
|
||||||
|
* If \a page is -1, guides from all pages will be returned.
|
||||||
*/
|
*/
|
||||||
QList< QgsLayoutGuide * > guides( QgsLayoutGuide::Orientation orientation );
|
QList< QgsLayoutGuide * > guides( QgsLayoutGuide::Orientation orientation, int page = -1 );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "qgslayout.h"
|
#include "qgslayout.h"
|
||||||
#include "qgis.h"
|
#include "qgis.h"
|
||||||
#include "qgslayoutview.h"
|
#include "qgslayoutview.h"
|
||||||
|
#include "qgslogger.h"
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <QGraphicsLineItem>
|
#include <QGraphicsLineItem>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
@ -52,6 +53,20 @@ QgsLayoutRuler::QgsLayoutRuler( QWidget *parent, Qt::Orientation orientation )
|
|||||||
mPixelsBetweenLineAndText = mRulerMinSize / 10;
|
mPixelsBetweenLineAndText = mRulerMinSize / 10;
|
||||||
mTextBaseline = mRulerMinSize / 1.667;
|
mTextBaseline = mRulerMinSize / 1.667;
|
||||||
mMinSpacingVerticalLabels = mRulerMinSize / 5;
|
mMinSpacingVerticalLabels = mRulerMinSize / 5;
|
||||||
|
|
||||||
|
double guideMarkerSize = mRulerFontMetrics->width( "*" );
|
||||||
|
switch ( mOrientation )
|
||||||
|
{
|
||||||
|
case Qt::Horizontal:
|
||||||
|
mGuideMarker << QPoint( -guideMarkerSize / 2, mRulerMinSize - guideMarkerSize ) << QPoint( 0, mRulerMinSize ) <<
|
||||||
|
QPoint( guideMarkerSize / 2, mRulerMinSize - guideMarkerSize );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::Vertical:
|
||||||
|
mGuideMarker << QPoint( mRulerMinSize - guideMarkerSize, -guideMarkerSize / 2 ) << QPoint( mRulerMinSize, 0 ) <<
|
||||||
|
QPoint( mRulerMinSize - guideMarkerSize, guideMarkerSize / 2 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize QgsLayoutRuler::minimumSizeHint() const
|
QSize QgsLayoutRuler::minimumSizeHint() const
|
||||||
@ -70,6 +85,8 @@ void QgsLayoutRuler::paintEvent( QPaintEvent *event )
|
|||||||
QgsLayout *layout = mView->currentLayout();
|
QgsLayout *layout = mView->currentLayout();
|
||||||
QPainter p( this );
|
QPainter p( this );
|
||||||
|
|
||||||
|
drawGuideMarkers( &p, layout );
|
||||||
|
|
||||||
QTransform t = mTransform.inverted();
|
QTransform t = mTransform.inverted();
|
||||||
p.setFont( mRulerFont );
|
p.setFont( mRulerFont );
|
||||||
// keep same default color, but lower opacity a tad
|
// keep same default color, but lower opacity a tad
|
||||||
@ -260,6 +277,56 @@ void QgsLayoutRuler::drawMarkerPos( QPainter *painter )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsLayoutRuler::drawGuideMarkers( QPainter *p, QgsLayout *layout )
|
||||||
|
{
|
||||||
|
QList< int > visiblePageNumbers = mView->visiblePageNumbers();
|
||||||
|
QList< QgsLayoutGuide * > guides = layout->guides().guides( mOrientation == Qt::Horizontal ? QgsLayoutGuide::Vertical : QgsLayoutGuide::Horizontal );
|
||||||
|
p->save();
|
||||||
|
p->setRenderHint( QPainter::Antialiasing, true );
|
||||||
|
p->setBrush( QBrush( QColor( 255, 0, 0 ) ) );
|
||||||
|
p->setPen( Qt::NoPen );
|
||||||
|
Q_FOREACH ( QgsLayoutGuide *guide, guides )
|
||||||
|
{
|
||||||
|
if ( visiblePageNumbers.contains( guide->page() ) )
|
||||||
|
{
|
||||||
|
QPointF point;
|
||||||
|
switch ( mOrientation )
|
||||||
|
{
|
||||||
|
case Qt::Horizontal:
|
||||||
|
point = QPointF( guide->layoutPosition(), 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::Vertical:
|
||||||
|
point = QPointF( 0, guide->layoutPosition() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
drawGuideAtPos( p, convertLayoutPointToLocal( point ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsLayoutRuler::drawGuideAtPos( QPainter *painter, QPoint pos )
|
||||||
|
{
|
||||||
|
switch ( mOrientation )
|
||||||
|
{
|
||||||
|
case Qt::Horizontal:
|
||||||
|
{
|
||||||
|
painter->translate( pos.x(), 0 );
|
||||||
|
painter->drawPolygon( mGuideMarker );
|
||||||
|
painter->translate( -pos.x(), 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Qt::Vertical:
|
||||||
|
{
|
||||||
|
painter->translate( 0, pos.y() );
|
||||||
|
painter->drawPolygon( mGuideMarker );
|
||||||
|
painter->translate( 0, -pos.y() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QgsLayoutRuler::createTemporaryGuideItem()
|
void QgsLayoutRuler::createTemporaryGuideItem()
|
||||||
{
|
{
|
||||||
mGuideItem.reset( new QGraphicsLineItem() );
|
mGuideItem.reset( new QGraphicsLineItem() );
|
||||||
@ -279,6 +346,12 @@ QPointF QgsLayoutRuler::convertLocalPointToLayout( QPoint localPoint ) const
|
|||||||
return mView->mapToScene( viewPoint );
|
return mView->mapToScene( viewPoint );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPoint QgsLayoutRuler::convertLayoutPointToLocal( QPointF layoutPoint ) const
|
||||||
|
{
|
||||||
|
QPoint viewPoint = mView->mapFromScene( layoutPoint );
|
||||||
|
return mapFromGlobal( mView->mapToGlobal( viewPoint ) );
|
||||||
|
}
|
||||||
|
|
||||||
void QgsLayoutRuler::drawRotatedText( QPainter *painter, QPointF pos, const QString &text )
|
void QgsLayoutRuler::drawRotatedText( QPainter *painter, QPointF pos, const QString &text )
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
@ -467,20 +540,19 @@ void QgsLayoutRuler::mouseMoveEvent( QMouseEvent *event )
|
|||||||
linePen.setColor( QColor( 255, 0, 0, 225 ) );
|
linePen.setColor( QColor( 255, 0, 0, 225 ) );
|
||||||
}
|
}
|
||||||
mGuideItem->setPen( linePen );
|
mGuideItem->setPen( linePen );
|
||||||
|
|
||||||
switch ( mOrientation )
|
switch ( mOrientation )
|
||||||
{
|
{
|
||||||
case Qt::Horizontal:
|
case Qt::Horizontal:
|
||||||
{
|
{
|
||||||
//mouse is creating a horizontal ruler, so don't show x coordinate
|
//mouse is creating a horizontal ruler, so don't show x coordinate
|
||||||
mGuideItem->setLine( 0, displayPos.y(), page->rect().width(), displayPos.y() );
|
mGuideItem->setLine( page->scenePos().x(), displayPos.y(), page->scenePos().x() + page->rect().width(), displayPos.y() );
|
||||||
displayPos.setX( 0 );
|
displayPos.setX( 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Vertical:
|
case Qt::Vertical:
|
||||||
{
|
{
|
||||||
//mouse is creating a vertical ruler, so don't show a y coordinate
|
//mouse is creating a vertical ruler, so don't show a y coordinate
|
||||||
mGuideItem->setLine( displayPos.x(), 0, displayPos.x(), page->rect().height() );
|
mGuideItem->setLine( displayPos.x(), page->scenePos().y(), displayPos.x(), page->scenePos().y() + page->rect().height() );
|
||||||
displayPos.setY( 0 );
|
displayPos.setY( 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,6 +111,9 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget
|
|||||||
bool mCreatingGuide = false;
|
bool mCreatingGuide = false;
|
||||||
std::unique_ptr< QGraphicsLineItem > mGuideItem;
|
std::unique_ptr< QGraphicsLineItem > mGuideItem;
|
||||||
|
|
||||||
|
//! Polygon for drawing guide markers
|
||||||
|
QPolygonF mGuideMarker;
|
||||||
|
|
||||||
//! Calculates the optimum labeled units for ruler so that labels are a good distance apart
|
//! Calculates the optimum labeled units for ruler so that labels are a good distance apart
|
||||||
int optimumScale( double minPixelDiff, int &magnitude, int &multiple );
|
int optimumScale( double minPixelDiff, int &magnitude, int &multiple );
|
||||||
|
|
||||||
@ -133,10 +136,17 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget
|
|||||||
//! Draw current marker pos on ruler
|
//! Draw current marker pos on ruler
|
||||||
void drawMarkerPos( QPainter *painter );
|
void drawMarkerPos( QPainter *painter );
|
||||||
|
|
||||||
|
void drawGuideMarkers( QPainter *painter, QgsLayout *layout );
|
||||||
|
|
||||||
|
//! Draw a guide marker on the ruler
|
||||||
|
void drawGuideAtPos( QPainter *painter, QPoint pos );
|
||||||
|
|
||||||
void createTemporaryGuideItem();
|
void createTemporaryGuideItem();
|
||||||
|
|
||||||
QPointF convertLocalPointToLayout( QPoint localPoint ) const;
|
QPointF convertLocalPointToLayout( QPoint localPoint ) const;
|
||||||
|
|
||||||
|
QPoint convertLayoutPointToLocal( QPointF layoutPoint ) const;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,19 @@ void QgsLayoutView::setCurrentLayout( QgsLayout *layout )
|
|||||||
mSnapMarker->hide();
|
mSnapMarker->hide();
|
||||||
layout->addItem( mSnapMarker.get() );
|
layout->addItem( mSnapMarker.get() );
|
||||||
|
|
||||||
|
if ( mHorizontalRuler )
|
||||||
|
{
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::dataChanged, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsInserted, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, mHorizontalRuler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
}
|
||||||
|
if ( mVerticalRuler )
|
||||||
|
{
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::dataChanged, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsInserted, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
}
|
||||||
|
|
||||||
//emit layoutSet, so that designer dialogs can update for the new layout
|
//emit layoutSet, so that designer dialogs can update for the new layout
|
||||||
emit layoutSet( layout );
|
emit layoutSet( layout );
|
||||||
}
|
}
|
||||||
@ -148,6 +161,12 @@ void QgsLayoutView::setHorizontalRuler( QgsLayoutRuler *ruler )
|
|||||||
{
|
{
|
||||||
mHorizontalRuler = ruler;
|
mHorizontalRuler = ruler;
|
||||||
ruler->setLayoutView( this );
|
ruler->setLayoutView( this );
|
||||||
|
if ( QgsLayout *layout = currentLayout() )
|
||||||
|
{
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::dataChanged, ruler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsInserted, ruler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, ruler, [ = ] { mHorizontalRuler->update(); } );
|
||||||
|
}
|
||||||
viewChanged();
|
viewChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +174,12 @@ void QgsLayoutView::setVerticalRuler( QgsLayoutRuler *ruler )
|
|||||||
{
|
{
|
||||||
mVerticalRuler = ruler;
|
mVerticalRuler = ruler;
|
||||||
ruler->setLayoutView( this );
|
ruler->setLayoutView( this );
|
||||||
|
if ( QgsLayout *layout = currentLayout() )
|
||||||
|
{
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::dataChanged, ruler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsInserted, ruler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
connect( &layout->guides(), &QAbstractItemModel::rowsRemoved, ruler, [ = ] { mVerticalRuler->update(); } );
|
||||||
|
}
|
||||||
viewChanged();
|
viewChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -149,7 +149,12 @@ class TestQgsLayoutGuide(unittest.TestCase):
|
|||||||
self.assertEqual(guides.data(guides.index(2, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters)
|
self.assertEqual(guides.data(guides.index(2, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters)
|
||||||
self.assertEqual(guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PageRole), 1)
|
self.assertEqual(guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PageRole), 1)
|
||||||
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2])
|
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2])
|
||||||
|
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0), [g1, g2])
|
||||||
|
self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 1), [])
|
||||||
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical), [g3])
|
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical), [g3])
|
||||||
|
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0), [])
|
||||||
|
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 1), [g3])
|
||||||
|
self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 2), [])
|
||||||
|
|
||||||
def testDeleteRows(self):
|
def testDeleteRows(self):
|
||||||
p = QgsProject()
|
p = QgsProject()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user