mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Drop composer class from gui library
This commit is contained in:
parent
073275479b
commit
322f2e8c38
@ -21,7 +21,7 @@ and QgsPropertyCollection).
|
||||
It allows users to specify field or expression based overrides
|
||||
which should be applied to a property of an object. Eg, this widget
|
||||
is used for controlling data defined overrides in symbology, labeling
|
||||
and composer.
|
||||
and layouts.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
@ -154,7 +154,6 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
|
||||
#include "qgsbrowserdockwidget.h"
|
||||
#include "qgsadvanceddigitizingdockwidget.h"
|
||||
#include "qgsclipboard.h"
|
||||
#include "qgscomposerview.h"
|
||||
#include "qgsconfigureshortcutsdialog.h"
|
||||
#include "qgscoordinatetransform.h"
|
||||
#include "qgscoordinateutils.h"
|
||||
|
@ -225,9 +225,6 @@ SET(QGIS_GUI_SRCS
|
||||
qgscolorschemelist.cpp
|
||||
qgscolorswatchgrid.cpp
|
||||
qgscolorwidgets.cpp
|
||||
qgscomposeritemcombobox.cpp
|
||||
qgscomposerruler.cpp
|
||||
qgscomposerview.cpp
|
||||
qgscompoundcolorwidget.cpp
|
||||
qgsconfigureshortcutsdialog.cpp
|
||||
qgscredentialdialog.cpp
|
||||
@ -400,10 +397,6 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgscolorschemelist.h
|
||||
qgscolorswatchgrid.h
|
||||
qgscolorwidgets.h
|
||||
qgscomposerinterface.h
|
||||
qgscomposeritemcombobox.h
|
||||
qgscomposerruler.h
|
||||
qgscomposerview.h
|
||||
qgscompoundcolorwidget.h
|
||||
qgsconfigureshortcutsdialog.h
|
||||
qgscredentialdialog.h
|
||||
@ -872,7 +865,6 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
qgscomposerinterface.h
|
||||
qgslayoutdesignerinterface.h
|
||||
---------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
|
@ -40,7 +40,7 @@ class QgsPropertyOverrideButton;
|
||||
// So QgsLayoutItemWidget HAS a QgsLayoutConfigObject to handle these common tasks.
|
||||
// Specific item property widgets (e.g., QgsLayoutMapWidget) should inherit from QgsLayoutItemBaseWidget
|
||||
// (which is a QgsPanelWidget) and also HAS a QgsLayoutConfigObject, with protected methods
|
||||
// which are just proxied through to the QgsComposerConfigObject.
|
||||
// which are just proxied through to the QgsLayoutConfigObject.
|
||||
// phew!
|
||||
// long story short - don't change this without good reason. If you add a new item type, inherit
|
||||
// from QgsLayoutItemBaseWidget and trust that everything else has been done for you.
|
||||
|
@ -319,7 +319,7 @@ double QgsLayoutMouseHandles::rectHandlerBorderTolerance()
|
||||
//get view scale factor
|
||||
double viewScaleFactor = mView->transform().m11();
|
||||
|
||||
//size of handle boxes depends on zoom level in composer view
|
||||
//size of handle boxes depends on zoom level in layout view
|
||||
double rectHandlerSize = 10.0 / viewScaleFactor;
|
||||
|
||||
//make sure the boxes don't get too large
|
||||
@ -510,7 +510,7 @@ QgsLayoutMouseHandles::MouseAction QgsLayoutMouseHandles::mouseActionForPosition
|
||||
QgsLayoutItem *item = dynamic_cast<QgsLayoutItem *>( graphicsItem );
|
||||
if ( item && item->isSelected() )
|
||||
{
|
||||
//cursor is over a selected composer item
|
||||
//cursor is over a selected layout item
|
||||
return QgsLayoutMouseHandles::MoveItem;
|
||||
}
|
||||
}
|
||||
|
@ -143,9 +143,9 @@ class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
|
||||
QPointF mLastMouseEventPos;
|
||||
//! Position of the mouse at beginning of move/resize (in scene coordinates)
|
||||
QPointF mBeginMouseEventPos;
|
||||
//! Position of composer handles at beginning of move/resize (in scene coordinates)
|
||||
//! Position of layout handles at beginning of move/resize (in scene coordinates)
|
||||
QPointF mBeginHandlePos;
|
||||
//! Width and height of composer handles at beginning of resize
|
||||
//! Width and height of layout handles at beginning of resize
|
||||
double mBeginHandleWidth = 0;
|
||||
double mBeginHandleHeight = 0;
|
||||
|
||||
@ -200,7 +200,7 @@ class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
|
||||
//sets the mouse cursor for the QGraphicsView attached to the composition (workaround qt bug #3732)
|
||||
void setViewportCursor( Qt::CursorShape cursor );
|
||||
|
||||
//resets the composer window status bar to the default message
|
||||
//resets the layout designer status bar to the default message
|
||||
void resetStatusBar();
|
||||
|
||||
//! Snaps an item or point (depending on mode) originating at originalPoint to the grid or align rulers
|
||||
|
@ -15,10 +15,12 @@
|
||||
#ifndef QGSLAYOUTRULER_H
|
||||
#define QGSLAYOUTRULER_H
|
||||
|
||||
#include "qgscomposeritem.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#include "qgis_gui.h"
|
||||
#include <QMenu>
|
||||
#include <memory>
|
||||
|
||||
class QgsLayout;
|
||||
class QGraphicsLineItem;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "qgslayoutpagecollection.h"
|
||||
#include "qgslayoutundostack.h"
|
||||
#include "qgslayoutreportsectionlabel.h"
|
||||
#include "qgsreadwritecontext.h"
|
||||
#include <memory>
|
||||
#include <QDesktopWidget>
|
||||
#include <QMenu>
|
||||
|
@ -320,7 +320,7 @@ QModelIndex QgsColorSchemeModel::index( int row, int column, const QModelIndex &
|
||||
|
||||
if ( !parent.isValid() && row >= 0 && row < mColors.size() )
|
||||
{
|
||||
//return an index for the composer item at this position
|
||||
//return an index for the color item at this position
|
||||
return createIndex( row, column );
|
||||
}
|
||||
|
||||
|
@ -1,71 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposerinterface.h
|
||||
---------------------
|
||||
Date : March 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERINTERFACE_H
|
||||
#define QGSCOMPOSERINTERFACE_H
|
||||
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
#include <QObject>
|
||||
|
||||
class QgsComposerView;
|
||||
class QgsComposition;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \class QgsComposerInterface
|
||||
* A common interface for composer dialogs.
|
||||
*
|
||||
* Provides a common interface and stable API for composer editor dialogs.
|
||||
* This interface can be used by plugins and scripts to interact with
|
||||
* open composer dialogs.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
* \note Not available in Python bindings
|
||||
* \deprecated Will be removed in QGIS 3.2
|
||||
*/
|
||||
class GUI_EXPORT QgsComposerInterface: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsComposerInterface.
|
||||
*/
|
||||
QgsComposerInterface( QObject *parent SIP_TRANSFERTHIS = nullptr )
|
||||
: QObject( parent )
|
||||
{}
|
||||
|
||||
/**
|
||||
* Returns the composer's QgsComposerView editor widget.
|
||||
*/
|
||||
virtual QgsComposerView *view() = 0;
|
||||
|
||||
/**
|
||||
* Returns the composition displated in the composer.
|
||||
*/
|
||||
virtual QgsComposition *composition() = 0;
|
||||
|
||||
/**
|
||||
* Closes the composer window.
|
||||
*/
|
||||
virtual void close() = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERINTERFACE_H
|
@ -1,120 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposeritemcombobox.cpp
|
||||
--------------------------------------
|
||||
Date : August 2014
|
||||
Copyright : (C) 2014 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposeritemcombobox.h"
|
||||
#include "qgscomposermodel.h"
|
||||
|
||||
QgsComposerItemComboBox::QgsComposerItemComboBox( QWidget *parent, QgsComposition *composition )
|
||||
: QComboBox( parent )
|
||||
|
||||
{
|
||||
setComposition( composition );
|
||||
|
||||
setModelColumn( QgsComposerModel::ItemId );
|
||||
connect( this, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsComposerItemComboBox::indexChanged );
|
||||
connect( mProxyModel, &QAbstractItemModel::rowsInserted, this, &QgsComposerItemComboBox::rowsChanged );
|
||||
connect( mProxyModel, &QAbstractItemModel::rowsRemoved, this, &QgsComposerItemComboBox::rowsChanged );
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::setComposition( QgsComposition *composition )
|
||||
{
|
||||
delete mProxyModel;
|
||||
mProxyModel = new QgsComposerProxyModel( composition, this );
|
||||
connect( mProxyModel, &QAbstractItemModel::rowsInserted, this, &QgsComposerItemComboBox::rowsChanged );
|
||||
connect( mProxyModel, &QAbstractItemModel::rowsRemoved, this, &QgsComposerItemComboBox::rowsChanged );
|
||||
setModel( mProxyModel );
|
||||
setModelColumn( QgsComposerModel::ItemId );
|
||||
mProxyModel->sort( 0, Qt::AscendingOrder );
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::setItem( const QgsComposerItem *item )
|
||||
{
|
||||
if ( !mProxyModel->sourceLayerModel() )
|
||||
return;
|
||||
|
||||
QModelIndex idx = mProxyModel->sourceLayerModel()->indexForItem( const_cast< QgsComposerItem * >( item ) );
|
||||
if ( idx.isValid() )
|
||||
{
|
||||
QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
|
||||
if ( proxyIdx.isValid() )
|
||||
{
|
||||
setCurrentIndex( proxyIdx.row() );
|
||||
emit itemChanged( currentItem() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
setCurrentIndex( -1 );
|
||||
emit itemChanged( currentItem() );
|
||||
}
|
||||
|
||||
QgsComposerItem *QgsComposerItemComboBox::currentItem() const
|
||||
{
|
||||
return item( currentIndex() );
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::indexChanged( int i )
|
||||
{
|
||||
Q_UNUSED( i );
|
||||
emit itemChanged( currentItem() );
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::rowsChanged()
|
||||
{
|
||||
if ( count() == 1 )
|
||||
{
|
||||
//currently selected item has changed
|
||||
emit itemChanged( currentItem() );
|
||||
}
|
||||
else if ( count() == 0 )
|
||||
{
|
||||
emit itemChanged( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::setItemType( QgsComposerItem::ItemType itemType )
|
||||
{
|
||||
mProxyModel->setFilterType( itemType );
|
||||
}
|
||||
|
||||
QgsComposerItem::ItemType QgsComposerItemComboBox::itemType() const
|
||||
{
|
||||
return mProxyModel->filterType();
|
||||
}
|
||||
|
||||
void QgsComposerItemComboBox::setExceptedItemList( const QList< QgsComposerItem *> &exceptList )
|
||||
{
|
||||
mProxyModel->setExceptedItemList( exceptList );
|
||||
}
|
||||
|
||||
QList< QgsComposerItem *> QgsComposerItemComboBox::exceptedItemList() const
|
||||
{
|
||||
return mProxyModel->exceptedItemList();
|
||||
}
|
||||
QgsComposerItem *QgsComposerItemComboBox::item( int index ) const
|
||||
{
|
||||
const QModelIndex proxyIndex = mProxyModel->index( index, 0 );
|
||||
if ( !proxyIndex.isValid() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
|
||||
if ( !sourceIndex.isValid() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mProxyModel->itemFromSourceIndex( sourceIndex );
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposeritemcombobox.h
|
||||
--------------------------------------
|
||||
Date : August 2014
|
||||
Copyright : (C) 2014 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERITEMCOMBOBOX_H
|
||||
#define QGSCOMPOSERITEMCOMBOBOX_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include "qgis.h"
|
||||
#include "qgscomposeritem.h"
|
||||
#include "qgis_gui.h"
|
||||
|
||||
class QgsComposerProxyModel;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
|
||||
/**
|
||||
* \class QgsComposerItemComboBox
|
||||
* \ingroup gui
|
||||
* \brief The QgsComposerItemComboBox class is a combo box which displays items of
|
||||
* a matching type from a composition.
|
||||
* \since QGIS 2.16
|
||||
* \note Not available in Python bindings
|
||||
* \deprecated Will be removed in QGIS 3.2
|
||||
*/
|
||||
class GUI_EXPORT QgsComposerItemComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* QgsComposerItemComboBox creates a combo box to display a list of items in a
|
||||
* composition. The items can optionally be filtered by type.
|
||||
* \param parent parent widget
|
||||
* \param composition composition to show items from. If not set, no items will be shown
|
||||
* until setComposition() is called
|
||||
*/
|
||||
explicit QgsComposerItemComboBox( QWidget *parent SIP_TRANSFERTHIS = nullptr, QgsComposition *composition = nullptr );
|
||||
|
||||
/**
|
||||
* Sets the composition containing the items to list in the combo box.
|
||||
*/
|
||||
void setComposition( QgsComposition *composition );
|
||||
|
||||
/**
|
||||
* Sets a filter for the item type to show in the combo box.
|
||||
* \param itemType type of items to show. Set to QgsComposerItem::ComposerItem to
|
||||
* show all items.
|
||||
* \see itemType()
|
||||
*/
|
||||
void setItemType( QgsComposerItem::ItemType itemType );
|
||||
|
||||
/**
|
||||
* Returns the filter for the item types to show in the combo box.
|
||||
* \see setItemType()
|
||||
*/
|
||||
QgsComposerItem::ItemType itemType() const;
|
||||
|
||||
/**
|
||||
* Sets a list of specific items to exclude from the combo box.
|
||||
* \param exceptList list of items to exclude
|
||||
* \see exceptedItemList()
|
||||
*/
|
||||
void setExceptedItemList( const QList< QgsComposerItem * > &exceptList );
|
||||
|
||||
/**
|
||||
* Returns the list of specific items excluded from the combo box.
|
||||
* \see setExceptedItemList()
|
||||
*/
|
||||
QList< QgsComposerItem * > exceptedItemList() const;
|
||||
|
||||
/**
|
||||
* Return the item currently shown at the specified index within the combo box.
|
||||
* \param index position of item to return
|
||||
* \see currentItem()
|
||||
*/
|
||||
QgsComposerItem *item( int index ) const;
|
||||
|
||||
/**
|
||||
* Returns the item currently selected in the combo box.
|
||||
*/
|
||||
QgsComposerItem *currentItem() const;
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* Sets the currently selected item in the combo box.
|
||||
* \param item selected item
|
||||
*/
|
||||
void setItem( const QgsComposerItem *item );
|
||||
|
||||
signals:
|
||||
|
||||
//! Emitted whenever the currently selected item changes
|
||||
void itemChanged( QgsComposerItem *item );
|
||||
|
||||
private slots:
|
||||
void indexChanged( int i );
|
||||
void rowsChanged();
|
||||
|
||||
private:
|
||||
QgsComposerProxyModel *mProxyModel = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERITEMCOMBOBOX_H
|
@ -1,513 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposerruler.cpp
|
||||
---------------------
|
||||
begin : January 2013
|
||||
copyright : (C) 2013 by Marco Hugentobler
|
||||
email : marco dot hugentobler at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgscomposerruler.h"
|
||||
#include "qgscomposition.h"
|
||||
#include "qgis.h"
|
||||
#include <QDragEnterEvent>
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
|
||||
const int RULER_FONT_SIZE = 8;
|
||||
const unsigned int COUNT_VALID_MULTIPLES = 3;
|
||||
const unsigned int COUNT_VALID_MAGNITUDES = 5;
|
||||
const int QgsComposerRuler::VALID_SCALE_MULTIPLES[] = {1, 2, 5};
|
||||
const int QgsComposerRuler::VALID_SCALE_MAGNITUDES[] = {1, 10, 100, 1000, 10000};
|
||||
|
||||
QgsComposerRuler::QgsComposerRuler( QgsComposerRuler::Direction d )
|
||||
: QWidget( nullptr )
|
||||
, mDirection( d )
|
||||
, mScaleMinPixelsWidth( 0 )
|
||||
{
|
||||
setMouseTracking( true );
|
||||
|
||||
//calculate minimum size required for ruler text
|
||||
mRulerFont = new QFont();
|
||||
mRulerFont->setPointSize( RULER_FONT_SIZE );
|
||||
mRulerFontMetrics = new QFontMetrics( *mRulerFont );
|
||||
|
||||
//calculate ruler sizes and marker separations
|
||||
|
||||
//minimum gap required between major ticks is 3 digits * 250%, based on appearance
|
||||
mScaleMinPixelsWidth = mRulerFontMetrics->width( QStringLiteral( "000" ) ) * 2.5;
|
||||
//minimum ruler height is twice the font height in pixels
|
||||
mRulerMinSize = mRulerFontMetrics->height() * 1.5;
|
||||
|
||||
mMinPixelsPerDivision = mRulerMinSize / 4;
|
||||
//each small division must be at least 2 pixels apart
|
||||
if ( mMinPixelsPerDivision < 2 )
|
||||
mMinPixelsPerDivision = 2;
|
||||
|
||||
mPixelsBetweenLineAndText = mRulerMinSize / 10;
|
||||
mTextBaseline = mRulerMinSize / 1.667;
|
||||
mMinSpacingVerticalLabels = mRulerMinSize / 5;
|
||||
}
|
||||
|
||||
QgsComposerRuler::~QgsComposerRuler()
|
||||
{
|
||||
delete mRulerFontMetrics;
|
||||
delete mRulerFont;
|
||||
}
|
||||
|
||||
QSize QgsComposerRuler::minimumSizeHint() const
|
||||
{
|
||||
return QSize( mRulerMinSize, mRulerMinSize );
|
||||
}
|
||||
|
||||
void QgsComposerRuler::paintEvent( QPaintEvent *event )
|
||||
{
|
||||
Q_UNUSED( event );
|
||||
if ( !mComposition )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPainter p( this );
|
||||
|
||||
QTransform t = mTransform.inverted();
|
||||
|
||||
p.setFont( *mRulerFont );
|
||||
|
||||
//find optimum scale for ruler (size of numbered divisions)
|
||||
int magnitude = 1;
|
||||
int multiple = 1;
|
||||
int mmDisplay;
|
||||
mmDisplay = optimumScale( mScaleMinPixelsWidth, magnitude, multiple );
|
||||
|
||||
//find optimum number of small divisions
|
||||
int numSmallDivisions = optimumNumberDivisions( mmDisplay, multiple );
|
||||
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
if ( qgsDoubleNear( width(), 0 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//start x-coordinate
|
||||
double startX = t.map( QPointF( 0, 0 ) ).x();
|
||||
double endX = t.map( QPointF( width(), 0 ) ).x();
|
||||
|
||||
//start marker position in mm
|
||||
double markerPos = ( std::floor( startX / mmDisplay ) + 1 ) * mmDisplay;
|
||||
|
||||
//draw minor ticks marks which occur before first major tick
|
||||
drawSmallDivisions( &p, markerPos, numSmallDivisions, -mmDisplay );
|
||||
|
||||
while ( markerPos <= endX )
|
||||
{
|
||||
double pixelCoord = mTransform.map( QPointF( markerPos, 0 ) ).x();
|
||||
|
||||
//draw large division and text
|
||||
p.drawLine( pixelCoord, 0, pixelCoord, mRulerMinSize );
|
||||
p.drawText( QPointF( pixelCoord + mPixelsBetweenLineAndText, mTextBaseline ), QString::number( markerPos ) );
|
||||
|
||||
//draw small divisions
|
||||
drawSmallDivisions( &p, markerPos, numSmallDivisions, mmDisplay, endX );
|
||||
|
||||
markerPos += mmDisplay;
|
||||
}
|
||||
}
|
||||
else //vertical
|
||||
{
|
||||
if ( qgsDoubleNear( height(), 0 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double startY = t.map( QPointF( 0, 0 ) ).y(); //start position in mm (total including space between pages)
|
||||
double endY = t.map( QPointF( 0, height() ) ).y(); //stop position in mm (total including space between pages)
|
||||
int startPage = ( int )( startY / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ) );
|
||||
if ( startPage < 0 )
|
||||
{
|
||||
startPage = 0;
|
||||
}
|
||||
|
||||
if ( startY < 0 )
|
||||
{
|
||||
double beforePageCoord = -mmDisplay;
|
||||
double firstPageY = mTransform.map( QPointF( 0, 0 ) ).y();
|
||||
|
||||
//draw negative rulers which fall before first page
|
||||
while ( beforePageCoord > startY )
|
||||
{
|
||||
double pixelCoord = mTransform.map( QPointF( 0, beforePageCoord ) ).y();
|
||||
p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord );
|
||||
//calc size of label
|
||||
QString label = QString::number( beforePageCoord );
|
||||
int labelSize = mRulerFontMetrics->width( label );
|
||||
|
||||
//draw label only if it fits in before start of next page
|
||||
if ( pixelCoord + labelSize + 8 < firstPageY )
|
||||
{
|
||||
drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label );
|
||||
}
|
||||
|
||||
//draw small divisions
|
||||
drawSmallDivisions( &p, beforePageCoord, numSmallDivisions, mmDisplay );
|
||||
|
||||
beforePageCoord -= mmDisplay;
|
||||
}
|
||||
|
||||
//draw minor ticks marks which occur before first major tick
|
||||
drawSmallDivisions( &p, beforePageCoord + mmDisplay, numSmallDivisions, -mmDisplay, startY );
|
||||
}
|
||||
|
||||
int endPage = ( int )( endY / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ) );
|
||||
if ( endPage > ( mComposition->numPages() - 1 ) )
|
||||
{
|
||||
endPage = mComposition->numPages() - 1;
|
||||
}
|
||||
|
||||
double nextPageStartPos = 0;
|
||||
int nextPageStartPixel = 0;
|
||||
|
||||
for ( int i = startPage; i <= endPage; ++i )
|
||||
{
|
||||
double pageCoord = 0; //page coordinate in mm
|
||||
//total (composition) coordinate in mm, including space between pages
|
||||
double totalCoord = i * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
|
||||
|
||||
//position of next page
|
||||
if ( i < endPage )
|
||||
{
|
||||
//not the last page
|
||||
nextPageStartPos = ( i + 1 ) * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
|
||||
nextPageStartPixel = mTransform.map( QPointF( 0, nextPageStartPos ) ).y();
|
||||
}
|
||||
else
|
||||
{
|
||||
//is the last page
|
||||
nextPageStartPos = 0;
|
||||
nextPageStartPixel = 0;
|
||||
}
|
||||
|
||||
while ( ( totalCoord < nextPageStartPos ) || ( ( nextPageStartPos == 0 ) && ( totalCoord <= endY ) ) )
|
||||
{
|
||||
double pixelCoord = mTransform.map( QPointF( 0, totalCoord ) ).y();
|
||||
p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord );
|
||||
//calc size of label
|
||||
QString label = QString::number( pageCoord );
|
||||
int labelSize = mRulerFontMetrics->width( label );
|
||||
|
||||
//draw label only if it fits in before start of next page
|
||||
if ( ( pixelCoord + labelSize + 8 < nextPageStartPixel )
|
||||
|| ( nextPageStartPixel == 0 ) )
|
||||
{
|
||||
drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label );
|
||||
}
|
||||
|
||||
//draw small divisions
|
||||
drawSmallDivisions( &p, totalCoord, numSmallDivisions, mmDisplay, nextPageStartPos );
|
||||
|
||||
pageCoord += mmDisplay;
|
||||
totalCoord += mmDisplay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//draw current marker pos
|
||||
drawMarkerPos( &p );
|
||||
}
|
||||
|
||||
void QgsComposerRuler::drawMarkerPos( QPainter *painter )
|
||||
{
|
||||
//draw current marker pos in red
|
||||
painter->setPen( QColor( Qt::red ) );
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
painter->drawLine( mMarkerPos.x(), 0, mMarkerPos.x(), mRulerMinSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->drawLine( 0, mMarkerPos.y(), mRulerMinSize, mMarkerPos.y() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerRuler::drawRotatedText( QPainter *painter, QPointF pos, const QString &text )
|
||||
{
|
||||
painter->save();
|
||||
painter->translate( pos.x(), pos.y() );
|
||||
painter->rotate( 270 );
|
||||
painter->drawText( 0, 0, text );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void QgsComposerRuler::drawSmallDivisions( QPainter *painter, double startPos, int numDivisions, double rulerScale, double maxPos )
|
||||
{
|
||||
if ( numDivisions == 0 )
|
||||
return;
|
||||
|
||||
//draw small divisions starting at startPos (in mm)
|
||||
double smallMarkerPos = startPos;
|
||||
double smallDivisionSpacing = rulerScale / numDivisions;
|
||||
|
||||
double pixelCoord;
|
||||
|
||||
//draw numDivisions small divisions
|
||||
for ( int i = 0; i < numDivisions; ++i )
|
||||
{
|
||||
smallMarkerPos += smallDivisionSpacing;
|
||||
|
||||
if ( maxPos > 0 && smallMarkerPos > maxPos )
|
||||
{
|
||||
//stop drawing current division position is past maxPos
|
||||
return;
|
||||
}
|
||||
|
||||
//calculate pixelCoordinate of the current division
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
pixelCoord = mTransform.map( QPointF( smallMarkerPos, 0 ) ).x();
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelCoord = mTransform.map( QPointF( 0, smallMarkerPos ) ).y();
|
||||
}
|
||||
|
||||
//calculate height of small division line
|
||||
double lineSize;
|
||||
if ( ( numDivisions == 10 && i == 4 ) || ( numDivisions == 4 && i == 1 ) )
|
||||
{
|
||||
//if drawing the 5th line of 10 or drawing the 2nd line of 4, then draw it slightly longer
|
||||
lineSize = mRulerMinSize / 1.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineSize = mRulerMinSize / 1.25;
|
||||
}
|
||||
|
||||
//draw either horizontal or vertical line depending on ruler direction
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
painter->drawLine( pixelCoord, lineSize, pixelCoord, mRulerMinSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->drawLine( lineSize, pixelCoord, mRulerMinSize, pixelCoord );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int QgsComposerRuler::optimumScale( double minPixelDiff, int &magnitude, int &multiple )
|
||||
{
|
||||
//find optimal ruler display scale
|
||||
|
||||
//loop through magnitudes and multiples to find optimum scale
|
||||
for ( unsigned int magnitudeCandidate = 0; magnitudeCandidate < COUNT_VALID_MAGNITUDES; ++magnitudeCandidate )
|
||||
{
|
||||
for ( unsigned int multipleCandidate = 0; multipleCandidate < COUNT_VALID_MULTIPLES; ++multipleCandidate )
|
||||
{
|
||||
int candidateScale = VALID_SCALE_MULTIPLES[multipleCandidate] * VALID_SCALE_MAGNITUDES[magnitudeCandidate];
|
||||
//find pixel size for each step using this candidate scale
|
||||
double pixelDiff = mTransform.map( QPointF( candidateScale, 0 ) ).x() - mTransform.map( QPointF( 0, 0 ) ).x();
|
||||
if ( pixelDiff > minPixelDiff )
|
||||
{
|
||||
//found the optimum major scale
|
||||
magnitude = VALID_SCALE_MAGNITUDES[magnitudeCandidate];
|
||||
multiple = VALID_SCALE_MULTIPLES[multipleCandidate];
|
||||
return candidateScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 100000;
|
||||
}
|
||||
|
||||
int QgsComposerRuler::optimumNumberDivisions( double rulerScale, int scaleMultiple )
|
||||
{
|
||||
//calculate size in pixels of each marked ruler unit
|
||||
double largeDivisionSize = mTransform.map( QPointF( rulerScale, 0 ) ).x() - mTransform.map( QPointF( 0, 0 ) ).x();
|
||||
|
||||
//now calculate optimum small tick scale, depending on marked ruler units
|
||||
QList<int> validSmallDivisions;
|
||||
switch ( scaleMultiple )
|
||||
{
|
||||
case 1:
|
||||
//numbers increase by 1 increment each time, e.g., 1, 2, 3 or 10, 20, 30
|
||||
//so we can draw either 10, 5 or 2 small ticks and have each fall on a nice value
|
||||
validSmallDivisions << 10 << 5 << 2;
|
||||
break;
|
||||
case 2:
|
||||
//numbers increase by 2 increments each time, e.g., 2, 4, 6 or 20, 40, 60
|
||||
//so we can draw either 10, 4 or 2 small ticks and have each fall on a nice value
|
||||
validSmallDivisions << 10 << 4 << 2;
|
||||
break;
|
||||
case 5:
|
||||
//numbers increase by 5 increments each time, e.g., 5, 10, 15 or 100, 500, 1000
|
||||
//so we can draw either 10 or 5 small ticks and have each fall on a nice value
|
||||
validSmallDivisions << 10 << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
//calculate the most number of small divisions we can draw without them being too close to each other
|
||||
QList<int>::iterator divisions_it;
|
||||
for ( divisions_it = validSmallDivisions.begin(); divisions_it != validSmallDivisions.end(); ++divisions_it )
|
||||
{
|
||||
//find pixel size for this small division
|
||||
double candidateSize = largeDivisionSize / ( *divisions_it );
|
||||
//check if this separation is more then allowed min separation
|
||||
if ( candidateSize >= mMinPixelsPerDivision )
|
||||
{
|
||||
//found a good candidate, return it
|
||||
return ( *divisions_it );
|
||||
}
|
||||
}
|
||||
|
||||
//unable to find a good candidate
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void QgsComposerRuler::setSceneTransform( const QTransform &transform )
|
||||
{
|
||||
#if 0
|
||||
QString debug = QString::number( transform.dx() ) + ',' + QString::number( transform.dy() ) + ','
|
||||
+ QString::number( transform.m11() ) + ',' + QString::number( transform.m22() );
|
||||
#endif
|
||||
mTransform = transform;
|
||||
update();
|
||||
}
|
||||
|
||||
void QgsComposerRuler::mouseMoveEvent( QMouseEvent *event )
|
||||
{
|
||||
//qWarning( "QgsComposerRuler::mouseMoveEvent" );
|
||||
updateMarker( event->pos() );
|
||||
setSnapLinePosition( event->pos() );
|
||||
|
||||
//update cursor position in status bar
|
||||
QPointF displayPos = mTransform.inverted().map( event->pos() );
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
//mouse is over a horizontal ruler, so don't show a y coordinate
|
||||
displayPos.setY( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
//mouse is over a vertical ruler, so don't show an x coordinate
|
||||
displayPos.setX( 0 );
|
||||
}
|
||||
emit cursorPosChanged( displayPos );
|
||||
}
|
||||
|
||||
void QgsComposerRuler::mouseReleaseEvent( QMouseEvent *event )
|
||||
{
|
||||
Q_UNUSED( event );
|
||||
|
||||
//remove snap line if coordinate under 0
|
||||
QPointF pos = mTransform.inverted().map( event->pos() );
|
||||
bool removeItem = false;
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
removeItem = pos.x() < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
removeItem = pos.y() < 0;
|
||||
}
|
||||
|
||||
if ( removeItem )
|
||||
{
|
||||
mComposition->removeSnapLine( mLineSnapItem );
|
||||
mSnappedItems.clear();
|
||||
}
|
||||
mLineSnapItem = nullptr;
|
||||
}
|
||||
|
||||
void QgsComposerRuler::mousePressEvent( QMouseEvent *event )
|
||||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
x = mTransform.inverted().map( event->pos() ).x();
|
||||
}
|
||||
else //vertical
|
||||
{
|
||||
y = mTransform.inverted().map( event->pos() ).y();
|
||||
}
|
||||
|
||||
//horizontal ruler means vertical snap line
|
||||
QGraphicsLineItem *line = mComposition->nearestSnapLine( mDirection != Horizontal, x, y, 10.0, mSnappedItems );
|
||||
if ( !line )
|
||||
{
|
||||
//create new snap line
|
||||
mLineSnapItem = mComposition->addSnapLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
mLineSnapItem = line;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerRuler::setSnapLinePosition( QPointF pos )
|
||||
{
|
||||
if ( !mLineSnapItem || !mComposition )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPointF transformedPt = mTransform.inverted().map( pos );
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
int numPages = mComposition->numPages();
|
||||
double lineHeight = numPages * mComposition->paperHeight();
|
||||
if ( numPages > 1 )
|
||||
{
|
||||
lineHeight += ( numPages - 1 ) * mComposition->spaceBetweenPages();
|
||||
}
|
||||
mLineSnapItem->setLine( QLineF( transformedPt.x(), 0, transformedPt.x(), lineHeight ) );
|
||||
}
|
||||
else //vertical
|
||||
{
|
||||
mLineSnapItem->setLine( QLineF( 0, transformedPt.y(), mComposition->paperWidth(), transformedPt.y() ) );
|
||||
}
|
||||
|
||||
//move snapped items together with the snap line
|
||||
QList< QPair< QgsComposerItem *, QgsComposerItem::ItemPositionMode > >::const_iterator itemIt = mSnappedItems.constBegin();
|
||||
for ( ; itemIt != mSnappedItems.constEnd(); ++itemIt )
|
||||
{
|
||||
if ( mDirection == Horizontal )
|
||||
{
|
||||
if ( itemIt->second == QgsComposerItem::MiddleLeft )
|
||||
{
|
||||
itemIt->first->setItemPosition( transformedPt.x(), itemIt->first->pos().y(), QgsComposerItem::UpperLeft );
|
||||
}
|
||||
else if ( itemIt->second == QgsComposerItem::Middle )
|
||||
{
|
||||
itemIt->first->setItemPosition( transformedPt.x(), itemIt->first->pos().y(), QgsComposerItem::UpperMiddle );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemIt->first->setItemPosition( transformedPt.x(), itemIt->first->pos().y(), QgsComposerItem::UpperRight );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( itemIt->second == QgsComposerItem::UpperMiddle )
|
||||
{
|
||||
itemIt->first->setItemPosition( itemIt->first->pos().x(), transformedPt.y(), QgsComposerItem::UpperLeft );
|
||||
}
|
||||
else if ( itemIt->second == QgsComposerItem::Middle )
|
||||
{
|
||||
itemIt->first->setItemPosition( itemIt->first->pos().x(), transformedPt.y(), QgsComposerItem::MiddleLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemIt->first->setItemPosition( itemIt->first->pos().x(), transformedPt.y(), QgsComposerItem::LowerLeft );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposerruler.h
|
||||
---------------------
|
||||
begin : January 2013
|
||||
copyright : (C) 2013 by Marco Hugentobler
|
||||
email : marco dot hugentobler at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSCOMPOSERRULER_H
|
||||
#define QGSCOMPOSERRULER_H
|
||||
|
||||
#include "qgscomposeritem.h"
|
||||
#include <QWidget>
|
||||
#include "qgis_gui.h"
|
||||
class QgsComposition;
|
||||
class QGraphicsLineItem;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* A class to show paper scale and the current cursor position.
|
||||
* \note Not available in Python bindings
|
||||
* \deprecated Will be removed in QGIS 3.2
|
||||
*/
|
||||
class GUI_EXPORT QgsComposerRuler: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Direction
|
||||
{
|
||||
Horizontal = 0,
|
||||
Vertical
|
||||
};
|
||||
|
||||
QgsComposerRuler( QgsComposerRuler::Direction d );
|
||||
~QgsComposerRuler() override;
|
||||
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
void setSceneTransform( const QTransform &transform );
|
||||
void updateMarker( QPointF pos ) { mMarkerPos = pos; repaint(); }
|
||||
|
||||
void setComposition( QgsComposition *c ) { mComposition = c; }
|
||||
QgsComposition *composition() { return mComposition; }
|
||||
|
||||
int rulerSize() { return mRulerMinSize; }
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent *event ) override;
|
||||
void mouseMoveEvent( QMouseEvent *event ) override;
|
||||
void mouseReleaseEvent( QMouseEvent *event ) override;
|
||||
void mousePressEvent( QMouseEvent *event ) override;
|
||||
|
||||
private:
|
||||
static const int VALID_SCALE_MULTIPLES[];
|
||||
static const int VALID_SCALE_MAGNITUDES[];
|
||||
|
||||
Direction mDirection;
|
||||
QTransform mTransform;
|
||||
QPointF mMarkerPos;
|
||||
QgsComposition *mComposition = nullptr; //reference to composition for paper size, nPages
|
||||
QGraphicsLineItem *mLineSnapItem = nullptr;
|
||||
//items snapped to the current snap line
|
||||
QList< QPair< QgsComposerItem *, QgsComposerItem::ItemPositionMode > > mSnappedItems;
|
||||
|
||||
QFont *mRulerFont = nullptr;
|
||||
QFontMetrics *mRulerFontMetrics = nullptr;
|
||||
double mScaleMinPixelsWidth;
|
||||
int mRulerMinSize;
|
||||
int mMinPixelsPerDivision;
|
||||
int mPixelsBetweenLineAndText;
|
||||
int mTextBaseline;
|
||||
int mMinSpacingVerticalLabels;
|
||||
|
||||
void setSnapLinePosition( QPointF pos );
|
||||
|
||||
//calculate optimum labeled units for ruler so that labels are a good distance apart
|
||||
int optimumScale( double minPixelDiff, int &magnitude, int &multiple );
|
||||
//calculate number of small divisions for each ruler unit, ensuring that they
|
||||
//are sufficiently spaced
|
||||
int optimumNumberDivisions( double rulerScale, int scaleMultiple );
|
||||
|
||||
//draws vertical text on a painter
|
||||
void drawRotatedText( QPainter *painter, QPointF pos, const QString &text );
|
||||
|
||||
/* Draws small ruler divisions
|
||||
* Starting at startPos in mm, for numDivisions divisions, with major division spacing of rulerScale (in mm)
|
||||
* Stop drawing if position exceeds maxPos
|
||||
*/
|
||||
void drawSmallDivisions( QPainter *painter, double startPos, int numDivisions, double rulerScale, double maxPos = 0 );
|
||||
|
||||
//draw current marker pos on ruler
|
||||
void drawMarkerPos( QPainter *painter );
|
||||
|
||||
signals:
|
||||
//! Is emitted when mouse cursor coordinates change
|
||||
void cursorPosChanged( QPointF );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERRULER_H
|
File diff suppressed because it is too large
Load Diff
@ -1,339 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgscomposerview.h
|
||||
-------------------
|
||||
begin : January 2005
|
||||
copyright : (C) 2005 by Radim Blazek
|
||||
email : blazek@itc.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSCOMPOSERVIEW_H
|
||||
#define QGSCOMPOSERVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include "qgis.h"
|
||||
#include "qgsprevieweffect.h" // for QgsPreviewEffect::PreviewMode
|
||||
#include <QGraphicsPolygonItem>
|
||||
#include "qgis_gui.h"
|
||||
#include <memory>
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
class QKeyEvent;
|
||||
class QMainWindow;
|
||||
class QMouseEvent;
|
||||
class QgsComposition;
|
||||
class QgsComposerArrow;
|
||||
class QgsComposerItem;
|
||||
class QgsComposerLabel;
|
||||
class QgsComposerLegend;
|
||||
class QgsComposerMap;
|
||||
class QgsComposerPicture;
|
||||
class QgsComposerRuler;
|
||||
class QgsComposerScaleBar;
|
||||
class QgsComposerShape;
|
||||
class QgsComposerNodesItem;
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsMapCanvas;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* Widget to display the composer items. Manages the composer tools and the
|
||||
* mouse/key events.
|
||||
* Creates the composer items according to the current map tools and keeps track
|
||||
* of the rubber band item.
|
||||
* \note Not available in Python bindings
|
||||
* \deprecated Will be removed in QGIS 3.2
|
||||
*/
|
||||
class GUI_EXPORT QgsComposerView: public QGraphicsView
|
||||
{
|
||||
|
||||
#ifdef SIP_RUN
|
||||
SIP_CONVERT_TO_SUBCLASS_CODE
|
||||
if ( sipCpp->inherits( "QgsComposerView" ) )
|
||||
sipType = sipType_QgsComposerView;
|
||||
else
|
||||
sipType = NULL;
|
||||
SIP_END
|
||||
#endif
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//! Current tool
|
||||
enum Tool
|
||||
{
|
||||
Select = 0, // Select/Move item
|
||||
AddArrow, // add arrow
|
||||
AddHtml,
|
||||
AddMap, // add new map
|
||||
AddLegend, // add vector legend
|
||||
AddLabel, // add label
|
||||
AddScalebar, // add scalebar
|
||||
AddPicture, // add raster/vector picture
|
||||
AddRectangle,
|
||||
AddEllipse,
|
||||
AddPolygon,
|
||||
AddPolyline,
|
||||
AddTriangle,
|
||||
AddTable, // add attribute table
|
||||
AddAttributeTable,
|
||||
MoveItemContent, // move content of item (e.g. content of map)
|
||||
EditNodesItem,
|
||||
Pan,
|
||||
Zoom
|
||||
};
|
||||
|
||||
enum ClipboardMode
|
||||
{
|
||||
ClipboardModeCut,
|
||||
ClipboardModeCopy
|
||||
};
|
||||
|
||||
enum PasteMode
|
||||
{
|
||||
PasteModeCursor,
|
||||
PasteModeCenter,
|
||||
PasteModeInPlace
|
||||
};
|
||||
|
||||
enum ToolStatus
|
||||
{
|
||||
Inactive,
|
||||
Active,
|
||||
ActiveUntilMouseRelease
|
||||
};
|
||||
|
||||
//! Constructor for QgsComposerView
|
||||
QgsComposerView( QWidget *parent SIP_TRANSFERTHIS = nullptr, const char *name = nullptr, Qt::WindowFlags f = nullptr );
|
||||
|
||||
//! Add an item group containing the selected items
|
||||
void groupItems();
|
||||
|
||||
//! Ungroups the selected items
|
||||
void ungroupItems();
|
||||
|
||||
//! Cuts or copies the selected items
|
||||
void copyItems( ClipboardMode mode );
|
||||
|
||||
//! Pastes items from clipboard
|
||||
void pasteItems( PasteMode mode );
|
||||
|
||||
//! Deletes selected items
|
||||
void deleteSelectedItems();
|
||||
|
||||
//! Selects all items
|
||||
void selectAll();
|
||||
|
||||
//! Deselects all items
|
||||
void selectNone();
|
||||
|
||||
//! Inverts current selection
|
||||
void selectInvert();
|
||||
|
||||
QgsComposerView::Tool currentTool() const {return mCurrentTool;}
|
||||
void setCurrentTool( QgsComposerView::Tool t );
|
||||
|
||||
/**
|
||||
* Sets the composition for the view. If the composition is being set manually and not by a QgsComposer, then this must
|
||||
* be set BEFORE adding any items to the composition.
|
||||
*/
|
||||
void setComposition( QgsComposition *c SIP_KEEPREFERENCE );
|
||||
|
||||
//! Returns the composition or 0 in case of error
|
||||
QgsComposition *composition();
|
||||
|
||||
//! Returns the composer main window
|
||||
QMainWindow *composerWindow();
|
||||
|
||||
void setPaintingEnabled( bool enabled ) { mPaintingEnabled = enabled; }
|
||||
bool paintingEnabled() const { return mPaintingEnabled; }
|
||||
|
||||
//! Update rulers with current scene rect
|
||||
void updateRulers();
|
||||
|
||||
void setHorizontalRuler( QgsComposerRuler *r ) { mHorizontalRuler = r; }
|
||||
void setVerticalRuler( QgsComposerRuler *r ) { mVerticalRuler = r; }
|
||||
|
||||
//! Set zoom level, where a zoom level of 1.0 corresponds to 100%
|
||||
void setZoomLevel( double zoomLevel );
|
||||
|
||||
/**
|
||||
* Scales the view in a safe way, by limiting the acceptable range
|
||||
* of the scale applied.
|
||||
* \param scale factor to scale view by
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
void scaleSafe( double scale );
|
||||
|
||||
/**
|
||||
* Sets whether a preview effect should be used to alter the view's appearance
|
||||
* \param enabled Set to true to enable the preview effect on the view
|
||||
* \since QGIS 2.3
|
||||
* \see setPreviewMode
|
||||
*/
|
||||
void setPreviewModeEnabled( bool enabled );
|
||||
|
||||
/**
|
||||
* Sets the preview mode which should be used to modify the view's appearance. Preview modes are only used
|
||||
* if setPreviewMode is set to true.
|
||||
* \param mode PreviewMode to be used to draw the view
|
||||
* \since QGIS 2.3
|
||||
* \see setPreviewModeEnabled
|
||||
*/
|
||||
void setPreviewMode( QgsPreviewEffect::PreviewMode mode );
|
||||
|
||||
/**
|
||||
* Sets the map canvas associated with the view. This allows the
|
||||
* view to retrieve map settings from the canvas.
|
||||
* \since QGIS 3.0
|
||||
* \see mapCanvas()
|
||||
*/
|
||||
void setMapCanvas( QgsMapCanvas *canvas );
|
||||
|
||||
/**
|
||||
* Returns the map canvas associated with the view.
|
||||
* \see setMapCanvas()
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsMapCanvas *mapCanvas() const;
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent * ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * ) override;
|
||||
void mouseMoveEvent( QMouseEvent * ) override;
|
||||
void mouseDoubleClickEvent( QMouseEvent *e ) override;
|
||||
|
||||
void keyPressEvent( QKeyEvent *e ) override;
|
||||
void keyReleaseEvent( QKeyEvent *e ) override;
|
||||
|
||||
void wheelEvent( QWheelEvent *event ) override;
|
||||
|
||||
void paintEvent( QPaintEvent *event ) override;
|
||||
|
||||
void hideEvent( QHideEvent *e ) override;
|
||||
void showEvent( QShowEvent *e ) override;
|
||||
|
||||
void resizeEvent( QResizeEvent *event ) override;
|
||||
void scrollContentsBy( int dx, int dy ) override;
|
||||
|
||||
private:
|
||||
//! Current composer tool
|
||||
QgsComposerView::Tool mCurrentTool = Select;
|
||||
//! Previous composer tool
|
||||
QgsComposerView::Tool mPreviousTool = Select;
|
||||
|
||||
//! Rubber band item
|
||||
QGraphicsRectItem *mRubberBandItem = nullptr;
|
||||
//! Rubber band item for arrows
|
||||
QGraphicsLineItem *mRubberBandLineItem = nullptr;
|
||||
//! Item to move content
|
||||
QgsComposerItem *mMoveContentItem = nullptr;
|
||||
//! Start position of content move
|
||||
QPointF mMoveContentStartPos;
|
||||
//! Start of rubber band creation
|
||||
QPointF mRubberBandStartPos;
|
||||
|
||||
//! True if user is currently selecting by marquee
|
||||
bool mMarqueeSelect = false;
|
||||
//! True if user is currently zooming by marquee
|
||||
bool mMarqueeZoom = false;
|
||||
//! True if user is currently temporarily activating the zoom tool by holding control+space
|
||||
QgsComposerView::ToolStatus mTemporaryZoomStatus = QgsComposerView::Inactive;
|
||||
|
||||
bool mPaintingEnabled = true;
|
||||
|
||||
QgsComposerRuler *mHorizontalRuler = nullptr;
|
||||
QgsComposerRuler *mVerticalRuler = nullptr;
|
||||
|
||||
QgsMapCanvas *mCanvas = nullptr;
|
||||
|
||||
//! Draw a shape on the canvas
|
||||
void addShape( Tool currentTool );
|
||||
|
||||
//! Point based shape stuff
|
||||
void addPolygonNode( QPointF scenePoint );
|
||||
void movePolygonNode( QPointF scenePoint, bool constrainAngle );
|
||||
void displayNodes( const bool display = true );
|
||||
void setSelectedNode( QgsComposerNodesItem *shape, const int index );
|
||||
void deselectNode();
|
||||
|
||||
float mMoveContentSearchRadius = 25;
|
||||
QgsComposerNodesItem *mNodesItem = nullptr;
|
||||
int mNodesItemIndex = -1;
|
||||
std::unique_ptr<QGraphicsPolygonItem> mPolygonItem;
|
||||
std::unique_ptr<QGraphicsPathItem> mPolylineItem;
|
||||
|
||||
//! True if user is currently panning by clicking and dragging with the pan tool
|
||||
bool mToolPanning = false;
|
||||
//! True if user is currently panning by holding the middle mouse button
|
||||
bool mMousePanning = false;
|
||||
//! True if user is currently panning by holding the space key
|
||||
bool mKeyPanning = false;
|
||||
|
||||
//! True if user is currently dragging with the move item content tool
|
||||
bool mMovingItemContent = false;
|
||||
|
||||
QPoint mMouseLastXY;
|
||||
QPoint mMouseCurrentXY;
|
||||
QPoint mMousePressStartPos;
|
||||
|
||||
QgsPreviewEffect *mPreviewEffect = nullptr;
|
||||
|
||||
//! Returns the default mouse cursor for a tool
|
||||
QCursor defaultCursorForTool( Tool currentTool );
|
||||
|
||||
//! Zoom composition from a mouse wheel event
|
||||
void wheelZoom( QWheelEvent *event );
|
||||
//! Redraws the rectangular rubber band
|
||||
void updateRubberBandRect( QPointF &pos, const bool constrainSquare = false, const bool fromCenter = false );
|
||||
//! Redraws the linear rubber band
|
||||
void updateRubberBandLine( QPointF pos, const bool constrainAngles = false );
|
||||
//! Removes the rubber band and cleans up
|
||||
void removeRubberBand();
|
||||
|
||||
//! Starts a marquee selection
|
||||
void startMarqueeSelect( QPointF &scenePoint );
|
||||
//! Finalises a marquee selection
|
||||
void endMarqueeSelect( QMouseEvent *e );
|
||||
//! Starts a zoom in marquee
|
||||
void startMarqueeZoom( QPointF &scenePoint );
|
||||
//! Finalises a marquee zoom
|
||||
void endMarqueeZoom( QMouseEvent *e );
|
||||
|
||||
//void connectAddRemoveCommandSignals( QgsAddRemoveItemCommand* c );
|
||||
|
||||
signals:
|
||||
//! Is emitted when selected item changed. If 0, no item is selected
|
||||
void selectedItemChanged( QgsComposerItem *selected );
|
||||
//! Is emitted when a composer item has been removed from the scene
|
||||
void itemRemoved( QgsComposerItem * );
|
||||
|
||||
/**
|
||||
* Current action (e.g. adding composer map) has been finished. The purpose of this signal is that
|
||||
QgsComposer may set the selection tool again*/
|
||||
void actionFinished();
|
||||
//! Is emitted when mouse cursor coordinates change
|
||||
void cursorPosChanged( QPointF );
|
||||
//! Is emitted when the view zoom changes
|
||||
void zoomLevelChanged();
|
||||
|
||||
//! Emitted before composerview is shown
|
||||
void composerViewShow( QgsComposerView * );
|
||||
//! Emitted before composerview is hidden
|
||||
void composerViewHide( QgsComposerView * );
|
||||
|
||||
//! Emitted when the composition is set for the view
|
||||
void compositionSet( QgsComposition * );
|
||||
};
|
||||
|
||||
#endif
|
@ -42,7 +42,7 @@ class QgsMapCanvas;
|
||||
* It allows users to specify field or expression based overrides
|
||||
* which should be applied to a property of an object. Eg, this widget
|
||||
* is used for controlling data defined overrides in symbology, labeling
|
||||
* and composer.
|
||||
* and layouts.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,6 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
@ -133,7 +132,6 @@ ADD_QGIS_TEST(editorwidgetregistrytest testqgseditorwidgetregistry.cpp)
|
||||
ADD_QGIS_TEST(keyvaluewidgettest testqgskeyvaluewidget.cpp)
|
||||
ADD_QGIS_TEST(listwidgettest testqgslistwidget.cpp)
|
||||
ADD_QGIS_TEST(filedownloader testqgsfiledownloader.cpp)
|
||||
ADD_QGIS_TEST(composergui testqgscomposergui.cpp)
|
||||
ADD_QGIS_TEST(layoutgui testqgslayoutgui.cpp)
|
||||
ADD_QGIS_TEST(layoutview testqgslayoutview.cpp)
|
||||
ADD_QGIS_TEST(valuerelationwidgetwrapper testqgsvaluerelationwidgetwrapper.cpp)
|
||||
|
@ -1,113 +0,0 @@
|
||||
/***************************************************************************
|
||||
testqgscomposergui.cpp
|
||||
----------------------
|
||||
Date : May 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgscomposition.h"
|
||||
#include "qgscomposerlabel.h"
|
||||
#include "qgscomposermap.h"
|
||||
#include "qgscomposermodel.h"
|
||||
#include "qgscomposeritemcombobox.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
|
||||
class TestQgsComposerGui: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase(); // will be called before the first testfunction is executed.
|
||||
void cleanupTestCase(); // will be called after the last testfunction was executed.
|
||||
void init(); // will be called before each testfunction is executed.
|
||||
void cleanup(); // will be called after every testfunction.
|
||||
|
||||
void testProxyCrash();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
void TestQgsComposerGui::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsComposerGui::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsComposerGui::init()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsComposerGui::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsComposerGui::testProxyCrash()
|
||||
{
|
||||
// test for a possible crash when using QgsComposerProxyModel and reordering items
|
||||
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
|
||||
|
||||
// create a composer item combobox
|
||||
QgsComposerItemComboBox *cb = new QgsComposerItemComboBox( nullptr, composition );
|
||||
QgsComposerItemComboBox *cb2 = new QgsComposerItemComboBox( nullptr, composition );
|
||||
QgsComposerItemComboBox *cb3 = new QgsComposerItemComboBox( nullptr, composition );
|
||||
QgsComposerItemComboBox *cb4 = new QgsComposerItemComboBox( nullptr, composition );
|
||||
|
||||
// add some items to composition
|
||||
QgsComposerMap *item1 = new QgsComposerMap( composition );
|
||||
composition->addItem( item1 );
|
||||
QgsComposerLabel *item2 = new QgsComposerLabel( composition );
|
||||
composition->addItem( item2 );
|
||||
QgsComposerMap *item3 = new QgsComposerMap( composition );
|
||||
composition->addItem( item3 );
|
||||
|
||||
QCOMPARE( cb->count(), 3 );
|
||||
cb->setItemType( QgsComposerItem::ComposerMap );
|
||||
QCOMPARE( cb->count(), 2 );
|
||||
|
||||
cb4->setItemType( QgsComposerItem::ComposerLabel );
|
||||
|
||||
cb->setItem( item1 );
|
||||
QCOMPARE( cb->currentItem(), item1 );
|
||||
cb2->setItem( item3 );
|
||||
QCOMPARE( cb2->currentItem(), item3 );
|
||||
cb3->setItem( item2 );
|
||||
QCOMPARE( cb3->currentItem(), item2 );
|
||||
|
||||
// reorder items - expect no crash!
|
||||
// we do this by calling the private members, in order to simulate what
|
||||
// happens when a drag and drop reorder occurs
|
||||
composition->itemsModel()->mItemZList.removeOne( item1 );
|
||||
composition->itemsModel()->mItemZList.insert( 1, item1 );
|
||||
composition->itemsModel()->rebuildSceneItemList();
|
||||
|
||||
QCOMPARE( cb->currentItem(), item1 );
|
||||
QCOMPARE( cb2->currentItem(), item3 );
|
||||
|
||||
composition->itemsModel()->mItemZList.removeOne( item1 );
|
||||
composition->itemsModel()->mItemZList.insert( 0, item1 );
|
||||
composition->itemsModel()->rebuildSceneItemList();
|
||||
|
||||
delete composition;
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN( TestQgsComposerGui )
|
||||
#include "testqgscomposergui.moc"
|
@ -67,7 +67,7 @@ void TestQgsLayoutGui::itemTypeComboBox()
|
||||
// test QgsLayoutItemComboBox
|
||||
QgsLayout *layout = new QgsLayout( QgsProject::instance() );
|
||||
|
||||
// create a composer item combobox
|
||||
// create a layout item combobox
|
||||
QgsLayoutItemComboBox *cb = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
QgsLayoutItemComboBox *cb2 = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
cb2->setItemType( QgsLayoutItemRegistry::LayoutShape );
|
||||
@ -76,7 +76,7 @@ void TestQgsLayoutGui::itemTypeComboBox()
|
||||
QSignalSpy spy1( cb, &QgsLayoutItemComboBox::itemChanged );
|
||||
QSignalSpy spy2( cb2, &QgsLayoutItemComboBox::itemChanged );
|
||||
|
||||
// add some items to composition
|
||||
// add some items to layout
|
||||
QgsLayoutItemMap *item1 = new QgsLayoutItemMap( layout );
|
||||
item1->setId( "item 1" );
|
||||
layout->addLayoutItem( item1 );
|
||||
@ -183,13 +183,13 @@ void TestQgsLayoutGui::testProxyCrash()
|
||||
// test for a possible crash when using QgsLayoutProxyModel and reordering items
|
||||
QgsLayout *layout = new QgsLayout( QgsProject::instance() );
|
||||
|
||||
// create a composer item combobox
|
||||
// create a layout item combobox
|
||||
QgsLayoutItemComboBox *cb = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
QgsLayoutItemComboBox *cb2 = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
QgsLayoutItemComboBox *cb3 = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
QgsLayoutItemComboBox *cb4 = new QgsLayoutItemComboBox( nullptr, layout );
|
||||
|
||||
// add some items to composition
|
||||
// add some items to layout
|
||||
QgsLayoutItemMap *item1 = new QgsLayoutItemMap( layout );
|
||||
layout->addLayoutItem( item1 );
|
||||
QCOMPARE( cb->count(), 1 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user