Skip to content

Commit

Permalink
Start of GUI for rule-based labeling
Browse files Browse the repository at this point in the history
This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s.
  • Loading branch information
wonder-sk committed Sep 24, 2015
1 parent 249c878 commit c30dd04
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 132 deletions.
4 changes: 4 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -42,9 +42,11 @@ SET(QGIS_APP_SRCS
qgslabelpropertydialog.cpp
qgslabelengineconfigdialog.cpp
qgslabelinggui.cpp
qgslabelingwidget.cpp
qgslabelpreview.cpp
qgsloadstylefromdbdialog.cpp
qgsmaplayerstyleguiutils.cpp
qgsrulebasedlabelingwidget.cpp
qgssavestyletodbdialog.cpp
qgsguivectorlayertools.cpp
qgswelcomepageitemsmodel.cpp
Expand Down Expand Up @@ -204,9 +206,11 @@ SET (QGIS_APP_MOC_HDRS
qgslabeldialog.h
qgslabelengineconfigdialog.h
qgslabelinggui.h
qgslabelingwidget.h
qgslabelpropertydialog.h
qgsloadstylefromdbdialog.h
qgsmaplayerstyleguiutils.h
qgsrulebasedlabelingwidget.h
qgssavestyletodbdialog.h
qgsshortcutsmanager.h
qgsapplayertreeviewmenuprovider.h
Expand Down
44 changes: 14 additions & 30 deletions src/app/qgslabelinggui.cpp
Expand Up @@ -23,7 +23,6 @@
#include <qgsmaplayerregistry.h>

#include "qgsdatadefinedbutton.h"
#include "qgslabelengineconfigdialog.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsexpression.h"
#include "qgsfontutils.h"
Expand Down Expand Up @@ -57,6 +56,7 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
: QWidget( parent )
, mLayer( layer )
, mMapCanvas( mapCanvas )
, mMode( NoLabels )
, mCharDlg( 0 )
, mQuadrantBtnGrp( 0 )
, mDirectSymbBtnGrp( 0 )
Expand Down Expand Up @@ -146,8 +146,6 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
connect( chkLineBelow, SIGNAL( toggled( bool ) ), this, SLOT( updateLinePlacementOptions() ) );
connect( chkLineOn, SIGNAL( toggled( bool ) ), this, SLOT( updateLinePlacementOptions() ) );

connect( btnEngineSettings, SIGNAL( clicked() ), this, SLOT( showEngineConfigDialog() ) );

// set placement methods page based on geometry type
switch ( layer->geometryType() )
{
Expand Down Expand Up @@ -314,17 +312,8 @@ void QgsLabelingGui::init()

blockInitSignals( true );

// enable/disable main options based upon whether layer is being labeled
if ( !lyr.enabled )
{
mLabelModeComboBox->setCurrentIndex( 0 );
}
else
{
mLabelModeComboBox->setCurrentIndex( lyr.drawLabels ? 1 : 2 );
}
mFieldExpressionWidget->setEnabled( mLabelModeComboBox->currentIndex() == 1 );
mLabelingFrame->setEnabled( mLabelModeComboBox->currentIndex() == 1 );
mFieldExpressionWidget->setEnabled( mMode == Labels );
mLabelingFrame->setEnabled( mMode == Labels );

// set the current field or add the current expression to the bottom of the list
mFieldExpressionWidget->setField( lyr.fieldName );
Expand Down Expand Up @@ -602,12 +591,20 @@ void QgsLabelingGui::writeSettingsToLayer()
settings.writeToLayer( mLayer );
}

void QgsLabelingGui::setLabelMode( LabelMode mode )
{
mMode = mode;

mFieldExpressionWidget->setEnabled( mMode == Labels );
mLabelingFrame->setEnabled( mMode == Labels );
}

QgsPalLayerSettings QgsLabelingGui::layerSettings()
{
QgsPalLayerSettings lyr;

lyr.enabled = mLabelModeComboBox->currentIndex() > 0;
lyr.drawLabels = mLabelModeComboBox->currentIndex() == 1;
lyr.enabled = ( mMode == Labels || mMode == ObstaclesOnly );
lyr.drawLabels = ( mMode == Labels );

bool isExpression;
lyr.fieldName = mFieldExpressionWidget->currentField( &isExpression );
Expand Down Expand Up @@ -680,7 +677,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
lyr.previewBkgrdColor = mPreviewBackgroundBtn->color();

lyr.priority = mPrioritySlider->value();
lyr.obstacle = mChkNoObstacle->isChecked() || mLabelModeComboBox->currentIndex() == 2;
lyr.obstacle = mChkNoObstacle->isChecked() || mMode == ObstaclesOnly;
lyr.obstacleFactor = mObstacleFactorSlider->value() / 50.0;
lyr.obstacleType = ( QgsPalLayerSettings::ObstacleType )mObstacleTypeComboBox->itemData( mObstacleTypeComboBox->currentIndex() ).toInt();
lyr.labelPerPart = chkLabelPerFeaturePart->isChecked();
Expand Down Expand Up @@ -1296,12 +1293,6 @@ void QgsLabelingGui::setPreviewBackground( QColor color )
QString::number( color.blue() ) ) );
}

void QgsLabelingGui::showEngineConfigDialog()
{
QgsLabelEngineConfigDialog dlg( this );
dlg.exec();
}

void QgsLabelingGui::syncDefinedCheckboxFrame( QgsDataDefinedButton* ddBtn, QCheckBox* chkBx, QFrame* f )
{
if ( ddBtn->isActive() && !chkBx->isChecked() )
Expand Down Expand Up @@ -1668,13 +1659,6 @@ void QgsLabelingGui::updateSvgWidgets( const QString& svgPath )
mShapeSVGUnitsLabel->setEnabled( validSVG && outlineWidthParam );
}

void QgsLabelingGui::on_mLabelModeComboBox_currentIndexChanged( int index )
{
bool labelsEnabled = ( index == 1 );
mFieldExpressionWidget->setEnabled( labelsEnabled );
mLabelingFrame->setEnabled( labelsEnabled );
}

void QgsLabelingGui::on_mShapeSVGSelectorBtn_clicked()
{
QgsSvgSelectorDialog svgDlg( this );
Expand Down
11 changes: 9 additions & 2 deletions src/app/qgslabelinggui.h
Expand Up @@ -39,12 +39,19 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
QgsPalLayerSettings layerSettings();
void writeSettingsToLayer();

enum LabelMode {
NoLabels,
Labels,
ObstaclesOnly,
};

void setLabelMode( LabelMode mode );

public slots:
void init();
void collapseSample( bool collapse );
void apply();
void changeTextColor( const QColor &color );
void showEngineConfigDialog();
void changeBufferColor( const QColor &color );

void updateUi();
Expand All @@ -53,7 +60,6 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
void updatePlacementWidgets();
void updateSvgWidgets( const QString& svgPath );

void on_mLabelModeComboBox_currentIndexChanged( int index );
void on_mPreviewSizeSlider_valueChanged( int i );
void on_mFontSizeSpinBox_valueChanged( double d );
void on_mFontCapitalsComboBox_currentIndexChanged( int index );
Expand Down Expand Up @@ -99,6 +105,7 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
private:
QgsVectorLayer* mLayer;
QgsMapCanvas* mMapCanvas;
LabelMode mMode;
QFontDatabase mFontDB;
QgsCharacterSelectorDialog* mCharDlg;

Expand Down
85 changes: 85 additions & 0 deletions src/app/qgslabelingwidget.cpp
@@ -0,0 +1,85 @@
#include "qgslabelingwidget.h"

#include "qgslabelengineconfigdialog.h"
#include "qgslabelinggui.h"
#include "qgsrulebasedlabelingwidget.h"
#include "qgsvectorlayerlabeling.h"

QgsLabelingWidget::QgsLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent )
: QWidget( parent )
, mLayer( layer )
, mCanvas( canvas )
{
setupUi( this );

connect( mEngineSettingsButton, SIGNAL( clicked() ), this, SLOT( showEngineConfigDialog() ) );

mWidgetSimple = new QgsLabelingGui( layer, canvas, this );
mWidgetRules = new QgsRuleBasedLabelingWidget( layer, canvas, this );
mStackedWidget->addWidget( mWidgetSimple );
mStackedWidget->addWidget( mWidgetRules );

mStackedWidget->setCurrentIndex( 0 );
}

void QgsLabelingWidget::init()
{
if ( !mLayer->labeling() || mLayer->labeling()->type() == "simple" )
{
mStackedWidget->setCurrentIndex( 0 );

// load labeling settings from layer
QgsPalLayerSettings lyr;
lyr.readFromLayer( mLayer );

// enable/disable main options based upon whether layer is being labeled
if ( !lyr.enabled )
{
mLabelModeComboBox->setCurrentIndex( 0 );
}
else
{
mLabelModeComboBox->setCurrentIndex( lyr.drawLabels ? 1 : 2 );
}

mWidgetSimple->init();
}
else if ( mLayer->labeling() && mLayer->labeling()->type() == "rule-based" )
{
mStackedWidget->setCurrentIndex( 1 );
mWidgetRules->init();
}
}

void QgsLabelingWidget::writeSettingsToLayer()
{
if ( mLabelModeComboBox->currentIndex() < 3 )
{
mWidgetSimple->writeSettingsToLayer();
}
else
{
mWidgetRules->writeSettingsToLayer();
}
}


void QgsLabelingWidget::on_mLabelModeComboBox_currentIndexChanged( int index )
{
if ( index < 3 )
{
mStackedWidget->setCurrentIndex( 0 );
mWidgetSimple->setLabelMode( ( QgsLabelingGui::LabelMode ) index );
}
else
{
// rule-based labeling
mStackedWidget->setCurrentIndex( 1 );
}
}

void QgsLabelingWidget::showEngineConfigDialog()
{
QgsLabelEngineConfigDialog dlg( this );
dlg.exec();
}
41 changes: 41 additions & 0 deletions src/app/qgslabelingwidget.h
@@ -0,0 +1,41 @@
#ifndef QGSLABELINGWIDGET_H
#define QGSLABELINGWIDGET_H

#include <QWidget>

#include <ui_qgslabelingwidget.h>

class QgsLabelingGui;
class QgsMapCanvas;
class QgsRuleBasedLabelingWidget;
class QgsVectorLayer;

/**
* Master widget for configuration of labeling of a vector layer
*/
class QgsLabelingWidget : public QWidget, private Ui::QgsLabelingWidget
{
Q_OBJECT
public:
QgsLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent = 0 );

//! load config from layer
void init();
//! save config to layer
void writeSettingsToLayer();

signals:

protected slots:
void on_mLabelModeComboBox_currentIndexChanged( int index );
void showEngineConfigDialog();

protected:
QgsVectorLayer* mLayer;
QgsMapCanvas* mCanvas;

QgsLabelingGui* mWidgetSimple;
QgsRuleBasedLabelingWidget* mWidgetRules;
};

#endif // QGSLABELINGWIDGET_H
20 changes: 20 additions & 0 deletions src/app/qgsrulebasedlabelingwidget.cpp
@@ -0,0 +1,20 @@
#include "qgsrulebasedlabelingwidget.h"

QgsRuleBasedLabelingWidget::QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent )
: QWidget( parent )
, mLayer( layer )
, mCanvas( canvas )
{
setupUi( this );
}

void QgsRuleBasedLabelingWidget::init()
{
// TODO
}

void QgsRuleBasedLabelingWidget::writeSettingsToLayer()
{
// TODO
}

31 changes: 31 additions & 0 deletions src/app/qgsrulebasedlabelingwidget.h
@@ -0,0 +1,31 @@
#ifndef QGSRULEBASEDLABELINGWIDGET_H
#define QGSRULEBASEDLABELINGWIDGET_H

#include <QWidget>

#include <ui_qgsrulebasedlabelingwidget.h>

class QgsMapCanvas;
class QgsVectorLayer;

class QgsRuleBasedLabelingWidget : public QWidget, private Ui::QgsRuleBasedLabelingWidget
{
Q_OBJECT
public:
QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent = 0 );

//! load config from layer
void init();
//! save config to layer
void writeSettingsToLayer();

signals:

public slots:

protected:
QgsVectorLayer* mLayer;
QgsMapCanvas* mCanvas;
};

#endif // QGSRULEBASEDLABELINGWIDGET_H
4 changes: 2 additions & 2 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -31,7 +31,7 @@
#include "qgsfieldcalculator.h"
#include "qgsfieldsproperties.h"
#include "qgslabeldialog.h"
#include "qgslabelinggui.h"
#include "qgslabelingwidget.h"
#include "qgslabel.h"
#include "qgsgenericprojectionselector.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -130,7 +130,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
// Create the Labeling dialog tab
layout = new QVBoxLayout( labelingFrame );
layout->setMargin( 0 );
labelingDialog = new QgsLabelingGui( layer, QgisApp::instance()->mapCanvas(), labelingFrame );
labelingDialog = new QgsLabelingWidget( layer, QgisApp::instance()->mapCanvas(), labelingFrame );
labelingDialog->layout()->setContentsMargins( -1, 0, -1, 0 );
layout->addWidget( labelingDialog );
labelingFrame->setLayout( layout );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsvectorlayerproperties.h
Expand Up @@ -37,7 +37,7 @@ class QgsAttributeActionDialog;
class QgsApplyDialog;
class QgsLabelDialog;
class QgsVectorLayer;
class QgsLabelingGui;
class QgsLabelingWidget;
class QgsDiagramProperties;
class QgsFieldsProperties;
class QgsRendererV2PropertiesDialog;
Expand Down Expand Up @@ -167,7 +167,7 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
/** Renderer dialog which is shown*/
QgsRendererV2PropertiesDialog* mRendererDialog;
/** Labeling dialog. If apply is pressed, options are applied to vector's QgsLabel */
QgsLabelingGui* labelingDialog;
QgsLabelingWidget* labelingDialog;
/** Label dialog. If apply is pressed, options are applied to vector's QgsLabel */
QgsLabelDialog* labelDialog;
/** Actions dialog. If apply is pressed, the actions are stored for later use */
Expand Down

0 comments on commit c30dd04

Please sign in to comment.