Add a lot of framework code for showing item properties in designer

And hook up a non-functional page properties widget which is
shown when right clicking on a page in the view.
This commit is contained in:
Nyall Dawson 2017-07-22 21:58:28 +10:00
parent 0f90e23fe6
commit 20029c2956
12 changed files with 385 additions and 12 deletions

View File

@ -28,7 +28,14 @@ class QgsLayoutItemAbstractGuiMetadata
%End
public:
QgsLayoutItemAbstractGuiMetadata( int type, const QString &groupId = QString() );
enum Flag
{
FlagNoCreationTools,
};
typedef QFlags<QgsLayoutItemAbstractGuiMetadata::Flag> Flags;
QgsLayoutItemAbstractGuiMetadata( int type, const QString &groupId = QString(), Flags flags = 0 );
%Docstring
Constructor for QgsLayoutItemAbstractGuiMetadata with the specified class ``type``.
@ -43,6 +50,12 @@ class QgsLayoutItemAbstractGuiMetadata
:rtype: int
%End
Flags flags() const;
%Docstring
Returns item flags.
:rtype: Flags
%End
QString groupId() const;
%Docstring
Returns the item group ID, if set.

View File

@ -158,6 +158,7 @@ SET(QGIS_APP_SRCS
layout/qgslayoutaddpagesdialog.cpp
layout/qgslayoutdesignerdialog.cpp
layout/qgslayoutappmenuprovider.cpp
layout/qgslayoutpagepropertieswidget.cpp
locator/qgsinbuiltlocatorfilters.cpp
locator/qgslocatoroptionswidget.cpp
@ -337,6 +338,7 @@ SET (QGIS_APP_MOC_HDRS
layout/qgslayoutaddpagesdialog.h
layout/qgslayoutappmenuprovider.h
layout/qgslayoutdesignerdialog.h
layout/qgslayoutpagepropertieswidget.h
locator/qgsinbuiltlocatorfilters.h
locator/qgslocatoroptionswidget.h

View File

@ -15,12 +15,14 @@
#include "qgslayoutappmenuprovider.h"
#include "qgslayoutitempage.h"
#include "qgslayoutdesignerdialog.h"
#include "qgslayout.h"
#include <QMenu>
#include <QMessageBox>
QgsLayoutAppMenuProvider::QgsLayoutAppMenuProvider( QObject *parent )
: QObject( parent )
QgsLayoutAppMenuProvider::QgsLayoutAppMenuProvider( QgsLayoutDesignerDialog *designer )
: QObject( nullptr )
, mDesigner( designer )
{
}
@ -34,10 +36,9 @@ QMenu *QgsLayoutAppMenuProvider::createContextMenu( QWidget *parent, QgsLayout *
if ( page )
{
QAction *pagePropertiesAction = new QAction( tr( "Page Properties…" ), menu );
connect( pagePropertiesAction, &QAction::triggered, this, [page]()
connect( pagePropertiesAction, &QAction::triggered, this, [this, page]()
{
mDesigner->showItemOptions( page );
} );
menu->addAction( pagePropertiesAction );
QAction *removePageAction = new QAction( tr( "Remove Page" ), menu );

View File

@ -20,6 +20,8 @@
#include "qgslayoutview.h"
#include <QObject>
class QgsLayoutDesignerDialog;
/**
* A menu provider for QgsLayoutView
*/
@ -29,10 +31,14 @@ class QgsLayoutAppMenuProvider : public QObject, public QgsLayoutViewMenuProvide
public:
QgsLayoutAppMenuProvider( QObject *parent = nullptr );
QgsLayoutAppMenuProvider( QgsLayoutDesignerDialog *designer );
QMenu *createContextMenu( QWidget *parent, QgsLayout *layout, QPointF layoutPoint ) const override;
private:
QgsLayoutDesignerDialog *mDesigner = nullptr;
};
#endif // QGSLAYOUTAPPMENUPROVIDER_H

View File

@ -27,10 +27,15 @@
#include "qgslayoutviewtoolpan.h"
#include "qgslayoutviewtoolzoom.h"
#include "qgslayoutviewtoolselect.h"
#include "qgslayoutitemwidget.h"
#include "qgsgui.h"
#include "qgslayoutitemguiregistry.h"
#include "qgslayoutruler.h"
#include "qgslayoutaddpagesdialog.h"
#include "qgspanelwidgetstack.h"
#include "qgspanelwidget.h"
#include "qgsdockwidget.h"
#include "qgslayoutpagepropertieswidget.h"
#include <QShortcut>
#include <QComboBox>
#include <QLineEdit>
@ -44,6 +49,8 @@ QList<double> QgsLayoutDesignerDialog::sStatusZoomLevelsList { 0.125, 0.25, 0.5,
#define FIT_LAYOUT -101
#define FIT_LAYOUT_WIDTH -102
bool QgsLayoutDesignerDialog::sInitializedRegistry = false;
QgsAppLayoutDesignerInterface::QgsAppLayoutDesignerInterface( QgsLayoutDesignerDialog *dialog )
: QgsLayoutDesignerInterface( dialog )
, mDesigner( dialog )
@ -70,6 +77,10 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
, mInterface( new QgsAppLayoutDesignerInterface( this ) )
, mToolsActionGroup( new QActionGroup( this ) )
{
if ( !sInitializedRegistry )
{
initializeRegistry();
}
QgsSettings settings;
int size = settings.value( QStringLiteral( "IconSize" ), QGIS_ICON_SIZE ).toInt();
setIconSize( QSize( size, size ) );
@ -222,9 +233,22 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
connect( mActionToggleFullScreen, &QAction::toggled, this, &QgsLayoutDesignerDialog::toggleFullScreen );
mMenuProvider = new QgsLayoutAppMenuProvider();
mMenuProvider = new QgsLayoutAppMenuProvider( this );
mView->setMenuProvider( mMenuProvider );
int minDockWidth( fontMetrics().width( QStringLiteral( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) ) );
mItemDock = new QgsDockWidget( tr( "Item properties" ), this );
mItemDock->setObjectName( QStringLiteral( "ItemDock" ) );
mItemDock->setMinimumWidth( minDockWidth );
mItemPropertiesStack = new QgsPanelWidgetStack();
mItemDock->setWidget( mItemPropertiesStack );
mPanelsMenu->addAction( mItemDock->toggleViewAction() );
addDockWidget( Qt::RightDockWidgetArea, mItemDock );
mItemDock->show();
restoreWindowState();
}
@ -257,6 +281,25 @@ void QgsLayoutDesignerDialog::setIconSizes( int size )
}
}
void QgsLayoutDesignerDialog::showItemOptions( QgsLayoutItem *item )
{
if ( !item )
{
delete mItemPropertiesStack->takeMainPanel();
return;
}
std::unique_ptr< QgsLayoutItemBaseWidget > widget( QgsGui::layoutItemGuiRegistry()->createItemWidget( item ) );
if ( ! widget )
{
return;
}
delete mItemPropertiesStack->takeMainPanel();
widget->setDockMode( true );
mItemPropertiesStack->setMainPanel( widget.release() );
}
void QgsLayoutDesignerDialog::open()
{
show();
@ -302,6 +345,9 @@ void QgsLayoutDesignerDialog::closeEvent( QCloseEvent * )
void QgsLayoutDesignerDialog::itemTypeAdded( int type )
{
if ( QgsGui::layoutItemGuiRegistry()->itemMetadata( type )->flags() & QgsLayoutItemAbstractGuiMetadata::FlagNoCreationTools )
return;
QString name = QgsApplication::layoutItemRegistry()->itemMetadata( type )->visibleName();
QString groupId = QgsGui::layoutItemGuiRegistry()->itemMetadata( type )->groupId();
QToolButton *groupButton = nullptr;
@ -532,4 +578,16 @@ void QgsLayoutDesignerDialog::activateNewItemCreationTool( int type )
}
}
void QgsLayoutDesignerDialog::initializeRegistry()
{
sInitializedRegistry = true;
auto createPageWidget = ( []( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
{
return new QgsLayoutPagePropertiesWidget( nullptr, item );
} );
QgsGui::layoutItemGuiRegistry()->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPage, QIcon(), createPageWidget, nullptr, QString(), QgsLayoutItemAbstractGuiMetadata::FlagNoCreationTools ) );
}

View File

@ -32,6 +32,9 @@ class QComboBox;
class QSlider;
class QLabel;
class QgsLayoutAppMenuProvider;
class QgsLayoutItem;
class QgsPanelWidgetStack;
class QgsDockWidget;
class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
{
@ -90,6 +93,10 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
*/
void setIconSizes( int size );
/**
* Shows the configuration widget for the specified layout \a item.
*/
void showItemOptions( QgsLayoutItem *item );
public slots:
@ -138,6 +145,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
private:
static bool sInitializedRegistry;
QgsAppLayoutDesignerInterface *mInterface = nullptr;
QgsLayout *mLayout = nullptr;
@ -170,6 +179,9 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
QgsLayoutAppMenuProvider *mMenuProvider;
QgsDockWidget *mItemDock = nullptr;
QgsPanelWidgetStack *mItemPropertiesStack = nullptr;
//! Save window state
void saveWindowState();
@ -179,6 +191,8 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
//! Switch to new item creation tool, for a new item of the specified \a type.
void activateNewItemCreationTool( int type );
void initializeRegistry();
};
#endif // QGSLAYOUTDESIGNERDIALOG_H

View File

@ -0,0 +1,25 @@
/***************************************************************************
qgslayoutpagepropertieswidget.cpp
---------------------------------
Date : July 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 "qgslayoutpagepropertieswidget.h"
#include "qgslayoutitempage.h"
QgsLayoutPagePropertiesWidget::QgsLayoutPagePropertiesWidget( QWidget *parent, QgsLayoutItem *layoutItem )
: QgsLayoutItemBaseWidget( parent, layoutItem )
, mPage( static_cast< QgsLayoutItemPage *>( layoutItem ) )
{
setupUi( this );
}

View File

@ -0,0 +1,52 @@
/***************************************************************************
qgslayoutpagepropertieswidget.h
-------------------------------
Date : July 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 QGSLAYOUTPAGEPROPERTIESWIDGET_H
#define QGSLAYOUTPAGEPROPERTIESWIDGET_H
#include "qgis.h"
#include "ui_qgslayoutpagepropertieswidget.h"
#include "qgslayoutsize.h"
#include "qgslayoutpoint.h"
#include "qgslayoutitemwidget.h"
#include "qgslayoutmeasurementconverter.h"
class QgsLayoutItem;
class QgsLayoutItemPage;
/**
* A widget for configuring properties of pages in a layout
*/
class QgsLayoutPagePropertiesWidget : public QgsLayoutItemBaseWidget, private Ui::QgsLayoutPagePropertiesWidget
{
Q_OBJECT
public:
/**
* Constructor for QgsLayoutPagePropertiesWidget.
*/
QgsLayoutPagePropertiesWidget( QWidget *parent, QgsLayoutItem *page );
private:
QgsLayoutItemPage *mPage = nullptr;
QgsLayoutMeasurementConverter mConverter;
};
#endif // QGSLAYOUTPAGEPROPERTIESWIDGET_H

View File

@ -42,6 +42,8 @@ bool QgsLayoutItemRegistry::populate()
};
addLayoutItemType( new QgsLayoutItemMetadata( 101, QStringLiteral( "temp type" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLabel.svg" ) ), createTemporaryItem ) );
addLayoutItemType( new QgsLayoutItemMetadata( LayoutPage, QStringLiteral( "Page" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileNew.svg" ) ), nullptr ) );
addLayoutItemType( new QgsLayoutItemMetadata( LayoutRectangle, QStringLiteral( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), QgsLayoutItemRectangularShape::create ) );
addLayoutItemType( new QgsLayoutItemMetadata( LayoutEllipse, QStringLiteral( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), QgsLayoutItemEllipseShape::create ) );
addLayoutItemType( new QgsLayoutItemMetadata( LayoutTriangle, QStringLiteral( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), QgsLayoutItemTriangleShape::create ) );

View File

@ -46,14 +46,22 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
{
public:
//! Flags for controlling how a items behave in the GUI
enum Flag
{
FlagNoCreationTools = 1 << 1, //!< Do not show item creation tools for the item type
};
Q_DECLARE_FLAGS( Flags, Flag )
/**
* Constructor for QgsLayoutItemAbstractGuiMetadata with the specified class \a type.
*
* An optional \a groupId can be set, which allows grouping of related layout item classes. See QgsLayoutItemGuiMetadata for details.
*/
QgsLayoutItemAbstractGuiMetadata( int type, const QString &groupId = QString() )
QgsLayoutItemAbstractGuiMetadata( int type, const QString &groupId = QString(), Flags flags = 0 )
: mType( type )
, mGroupId( groupId )
, mFlags( flags )
{}
virtual ~QgsLayoutItemAbstractGuiMetadata() = default;
@ -63,6 +71,11 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
*/
int type() const { return mType; }
/**
* Returns item flags.
*/
Flags flags() const { return mFlags; }
/**
* Returns the item group ID, if set.
*/
@ -88,6 +101,7 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
int mType = -1;
QString mGroupId;
Flags mFlags;
};
@ -118,8 +132,8 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad
*/
QgsLayoutItemGuiMetadata( int type, const QIcon &creationIcon,
QgsLayoutItemWidgetFunc pfWidget = nullptr,
QgsLayoutItemRubberBandFunc pfRubberBand = nullptr, const QString &groupId = QString() )
: QgsLayoutItemAbstractGuiMetadata( type, groupId )
QgsLayoutItemRubberBandFunc pfRubberBand = nullptr, const QString &groupId = QString(), QgsLayoutItemAbstractGuiMetadata::Flags flags = 0 )
: QgsLayoutItemAbstractGuiMetadata( type, groupId, flags )
, mIcon( creationIcon )
, mWidgetFunc( pfWidget )
, mRubberBandFunc( pfRubberBand )

View File

@ -83,7 +83,7 @@
<x>0</x>
<y>0</y>
<width>1083</width>
<height>25</height>
<height>42</height>
</rect>
</property>
<widget class="QMenu" name="mLayoutMenu">
@ -107,6 +107,11 @@
<string>&amp;Toolbars</string>
</property>
</widget>
<widget class="QMenu" name="mPanelsMenu">
<property name="title">
<string>&amp;Panels</string>
</property>
</widget>
<addaction name="mActionZoomIn"/>
<addaction name="mActionZoomOut"/>
<addaction name="mActionZoomActual"/>
@ -116,6 +121,7 @@
<addaction name="mActionShowRulers"/>
<addaction name="separator"/>
<addaction name="mToolbarMenu"/>
<addaction name="mPanelsMenu"/>
<addaction name="mActionToggleFullScreen"/>
</widget>
<addaction name="mLayoutMenu"/>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsLayoutPagePropertiesWidget</class>
<widget class="QWidget" name="QgsLayoutPagePropertiesWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>660</width>
<height>368</height>
</rect>
</property>
<property name="windowTitle">
<string>New Item Properties</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Page size</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mWidthLabel">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mPageOrientationComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Orientation</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mPageSizeComboBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mHeightLabel">
<property name="text">
<string>Height</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,0,0,0,1">
<item row="0" column="4" rowspan="2">
<widget class="QgsLayoutUnitsComboBox" name="mSizeUnitsComboBox"/>
</item>
<item row="0" column="3" rowspan="2">
<layout class="QHBoxLayout" name="_2">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QgsRatioLockButton" name="mLockAspectRatio">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Lock aspect ratio (including while drawing extent onto canvas)</string>
</property>
<property name="leftMargin" stdset="0">
<number>13</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="3">
<widget class="QgsDoubleSpinBox" name="mWidthSpin">
<property name="suffix">
<string/>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QgsDoubleSpinBox" name="mHeightSpin">
<property name="suffix">
<string/>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsRatioLockButton</class>
<extends>QToolButton</extends>
<header>qgsratiolockbutton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsLayoutUnitsComboBox</class>
<extends>QComboBox</extends>
<header>qgslayoutunitscombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mPageSizeComboBox</tabstop>
<tabstop>mPageOrientationComboBox</tabstop>
<tabstop>mWidthSpin</tabstop>
<tabstop>mHeightSpin</tabstop>
<tabstop>mLockAspectRatio</tabstop>
<tabstop>mSizeUnitsComboBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>