Skip to content

Commit 831e7cd

Browse files
committedApr 19, 2016
[FEATURE][styles] Add new style dock for interactive styling
1 parent b7a43f2 commit 831e7cd

18 files changed

+1362
-932
lines changed
 

‎python/gui/qgsfieldexpressionwidget.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class QgsFieldExpressionWidget : QWidget
8484
//! convenience slot to connect QgsMapLayerComboBox layer signal
8585
void setLayer( QgsMapLayer* layer );
8686

87+
//! sets the current row in the widget
88+
void setRow( int row );
89+
8790
//! sets the current field or expression in the widget
8891
void setField( const QString &fieldName );
8992

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ SET(QGIS_APP_SRCS
9494
nodetool/qgsvertexentry.cpp
9595
nodetool/qgsnodeeditor.cpp
9696

97+
qgsmapstylingwidget.cpp
9798
qgsmeasuredialog.cpp
9899
qgsmeasuretool.cpp
99100
qgsmergeattributesdialog.cpp
@@ -268,6 +269,7 @@ SET (QGIS_APP_MOC_HDRS
268269
nodetool/qgsselectedfeature.h
269270
nodetool/qgsnodeeditor.h
270271

272+
qgsmapstylingwidget.h
271273
qgsmeasuredialog.h
272274
qgsmeasuretool.h
273275
qgsmergeattributesdialog.h

‎src/app/qgisapp.cpp

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include <qgsnetworkaccessmanager.h>
7676
#include <qgsapplication.h>
7777
#include <qgscomposition.h>
78+
#include <qgsmapstylingwidget.h>
7879

7980
#include <QNetworkReply>
8081
#include <QNetworkProxy>
@@ -716,6 +717,16 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
716717
addDockWidget( Qt::LeftDockWidgetArea, mUndoWidget );
717718
mUndoWidget->hide();
718719

720+
mMapStylingDock = new QDockWidget( this );
721+
mMapStylingDock->setWindowTitle( tr( "Map Styling" ) );
722+
mMapStyleWidget = new QgsMapStylingWidget( mMapCanvas );
723+
mMapStylingDock->setWidget( mMapStyleWidget );
724+
725+
connect( mMapStyleWidget, SIGNAL( styleChanged( QgsMapLayer* ) ), this, SLOT( updateLabelToolButtons() ) );
726+
727+
addDockWidget( Qt::RightDockWidgetArea, mMapStylingDock );
728+
mMapStylingDock->hide();
729+
719730
mSnappingDialog = new QgsSnappingDialog( this, mMapCanvas );
720731
mSnappingDialog->setObjectName( "SnappingOption" );
721732

@@ -2399,6 +2410,9 @@ void QgisApp::setupConnections()
23992410
// connect legend signals
24002411
connect( mLayerTreeView, SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
24012412
this, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer * ) ) );
2413+
connect( mLayerTreeView, SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
2414+
this, SLOT( setMapStyleDockLayer( QgsMapLayer* ) ) );
2415+
24022416
connect( mLayerTreeView->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ),
24032417
this, SLOT( legendLayerSelectionChanged() ) );
24042418
connect( mLayerTreeView->layerTreeModel()->rootGroup(), SIGNAL( addedChildren( QgsLayerTreeNode*, int, int ) ),
@@ -2748,6 +2762,11 @@ void QgisApp::initLayerTreeView()
27482762
mLegendExpressionFilterButton->setToolTip( tr( "Filter legend by expression" ) );
27492763
connect( mLegendExpressionFilterButton, SIGNAL( toggled( bool ) ), this, SLOT( toggleFilterLegendByExpression( bool ) ) );
27502764

2765+
mActionStyleDock = new QAction( tr( "Map Styling" ), this );
2766+
mActionStyleDock->setToolTip( tr( "Open the map styling dock" ) );
2767+
mActionStyleDock->setIcon( QgsApplication::getThemeIcon( "propertyicons/symbology.png" ) );
2768+
connect( mActionStyleDock, SIGNAL( triggered() ), this, SLOT( mapStyleDock() ) );
2769+
27512770
// expand / collapse tool buttons
27522771
QAction* actionExpandAll = new QAction( tr( "Expand All" ), this );
27532772
actionExpandAll->setIcon( QgsApplication::getThemeIcon( "/mActionExpandTree.svg" ) );
@@ -2758,6 +2777,9 @@ void QgisApp::initLayerTreeView()
27582777
actionCollapseAll->setToolTip( tr( "Collapse All" ) );
27592778
connect( actionCollapseAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( collapseAll() ) );
27602779

2780+
QWidget* spacer = new QWidget();
2781+
spacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
2782+
27612783
QToolBar* toolbar = new QToolBar();
27622784
toolbar->setIconSize( QSize( 16, 16 ) );
27632785
toolbar->addAction( actionAddGroup );
@@ -2767,6 +2789,8 @@ void QgisApp::initLayerTreeView()
27672789
toolbar->addAction( actionExpandAll );
27682790
toolbar->addAction( actionCollapseAll );
27692791
toolbar->addAction( mActionRemoveLayer );
2792+
toolbar->addWidget( spacer );
2793+
toolbar->addAction( mActionStyleDock );
27702794

27712795
QVBoxLayout* vboxLayout = new QVBoxLayout;
27722796
vboxLayout->setMargin( 0 );
@@ -5460,47 +5484,33 @@ void QgisApp::labeling()
54605484
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer*>( activeLayer() );
54615485
if ( !vlayer )
54625486
{
5463-
messageBar()->pushMessage( tr( "Labeling Options" ),
5464-
tr( "Please select a vector layer first" ),
5465-
QgsMessageBar::INFO,
5466-
messageTimeout() );
54675487
return;
54685488
}
54695489

5490+
mapStyleDock();
5491+
}
54705492

5471-
QDialog dlg;
5472-
dlg.setWindowTitle( tr( "Layer labeling settings" ) );
5473-
QgsLabelingWidget *labelingGui = new QgsLabelingWidget( vlayer, mMapCanvas, &dlg );
5474-
labelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
5475-
QVBoxLayout *layout = new QVBoxLayout( &dlg );
5476-
layout->addWidget( labelingGui );
5477-
5478-
QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply, Qt::Horizontal, &dlg );
5479-
layout->addWidget( buttonBox );
5480-
5481-
dlg.setLayout( layout );
5482-
5483-
QSettings settings;
5484-
dlg.restoreGeometry( settings.value( "/Windows/Labeling/geometry" ).toByteArray() );
5485-
5486-
connect( buttonBox->button( QDialogButtonBox::Ok ), SIGNAL( clicked() ), &dlg, SLOT( accept() ) );
5487-
connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL( clicked() ), &dlg, SLOT( reject() ) );
5488-
connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), labelingGui, SLOT( apply() ) );
5489-
5490-
if ( dlg.exec() )
5493+
void QgisApp::setMapStyleDockLayer( QgsMapLayer* layer )
5494+
{
5495+
if ( !layer )
54915496
{
5492-
labelingGui->writeSettingsToLayer();
5497+
mMapStylingDock->setEnabled( false );
5498+
return;
5499+
}
54935500

5494-
settings.setValue( "/Windows/Labeling/geometry", dlg.saveGeometry() );
5501+
mMapStylingDock->setEnabled( true );
5502+
// We don't set the layer if the dock isn't open mainly to save
5503+
// the extra work if it's not needed
5504+
if ( mMapStylingDock->isVisible() )
5505+
mMapStyleWidget->setLayer( layer );
54955506

5496-
// trigger refresh
5497-
if ( mMapCanvas )
5498-
{
5499-
mMapCanvas->refresh();
5500-
}
5501-
}
5507+
mMapStylingDock->setWindowTitle( tr( "Map Styling - %1" ).arg( layer->name() ) );
5508+
}
55025509

5503-
activateDeactivateLayerRelatedActions( vlayer );
5510+
void QgisApp::mapStyleDock()
5511+
{
5512+
mMapStylingDock->show();
5513+
setMapStyleDockLayer( activeLayer() );
55045514
}
55055515

55065516
void QgisApp::diagramProperties()
@@ -9848,7 +9858,7 @@ void QgisApp::layerEditStateChanged()
98489858
}
98499859
}
98509860

9851-
void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
9861+
void QgisApp::updateLabelToolButtons()
98529862
{
98539863
bool enableMove = false, enableRotate = false, enablePin = false, enableShowHide = false, enableChange = false;
98549864

@@ -9895,6 +9905,11 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
98959905
mActionMoveLabel->setEnabled( enableMove );
98969906
mActionRotateLabel->setEnabled( enableRotate );
98979907
mActionChangeLabelProperties->setEnabled( enableChange );
9908+
}
9909+
9910+
void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
9911+
{
9912+
updateLabelToolButtons();
98989913

98999914
mMenuPasteAs->setEnabled( clipboard() && !clipboard()->isEmpty() );
99009915
mActionPasteAsNewVector->setEnabled( clipboard() && !clipboard()->isEmpty() );

‎src/app/qgisapp.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
* it under the terms of the GNU General Public License as published by *
1313
* the Free Software Foundation; either version 2 of the License, or *
1414
* (at your option) any later version. *
15-
* *
16-
***************************************************************************/
15+
* * ***************************************************************************/
1716

1817
#ifndef QGISAPP_H
1918
#define QGISAPP_H
@@ -94,6 +93,8 @@ class QgsScaleComboBox;
9493
class QgsDataItem;
9594
class QgsTileScaleWidget;
9695

96+
class QgsLabelingWidget;
97+
class QgsMapStylingWidget;
9798
class QgsDiagramProperties;
9899

99100
#include <QMainWindow>
@@ -115,6 +116,7 @@ class QgsDiagramProperties;
115116
#include "qgsbookmarks.h"
116117
#include "qgswelcomepageitemsmodel.h"
117118

119+
118120
#include "ui_qgisapp.h"
119121

120122
#ifdef HAVE_TOUCH
@@ -1089,6 +1091,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
10891091
/** Called when some layer's editing mode was toggled on/off */
10901092
void layerEditStateChanged();
10911093

1094+
/** Update the label toolbar buttons */
1095+
void updateLabelToolButtons();
1096+
10921097
/** Activates or deactivates actions depending on the current maplayer type.
10931098
Is called from the legend when the current legend item has changed*/
10941099
void activateDeactivateLayerRelatedActions( QgsMapLayer *layer );
@@ -1164,6 +1169,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
11641169
//! shows label settings dialog (for labeling-ng)
11651170
void labeling();
11661171

1172+
//! shows the map styling dock
1173+
void mapStyleDock();
1174+
11671175
//! diagrams properties
11681176
void diagramProperties();
11691177

@@ -1285,6 +1293,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
12851293
/** Pushes a layer error to the message bar */
12861294
void onLayerError( const QString& msg );
12871295

1296+
/** Set the layer for the map style dock. Doesn't show the style dock */
1297+
void setMapStyleDockLayer( QgsMapLayer *layer );
1298+
12881299
signals:
12891300
/** Emitted when a key is pressed and we want non widget sublasses to be able
12901301
to pick up on this (e.g. maplayer) */
@@ -1682,6 +1693,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
16821693
QgsSnappingDialog *mSnappingDialog;
16831694

16841695
QgsPluginManager *mPluginManager;
1696+
QDockWidget *mMapStylingDock;
1697+
QgsMapStylingWidget* mMapStyleWidget;
16851698

16861699
QgsComposerManager *mComposerManager;
16871700

@@ -1720,6 +1733,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
17201733
QgsMapCanvasTracer* mTracer;
17211734

17221735
QAction* mActionFilterLegend;
1736+
QAction* mActionStyleDock;
17231737

17241738
QgsLegendFilterButton* mLegendExpressionFilterButton;
17251739

‎src/app/qgslabelinggui.cpp

Lines changed: 352 additions & 54 deletions
Large diffs are not rendered by default.

‎src/app/qgslabelinggui.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
4848

4949
void setLabelMode( LabelMode mode );
5050

51+
signals:
52+
void widgetChanged();
53+
5154
public slots:
55+
void setLayer( QgsMapLayer* layer );
56+
void setDockMode( bool enabled );
57+
void connectValueChanged( QList<QWidget*> widgets, const char* slot );
58+
5259
void init();
5360
void collapseSample( bool collapse );
5461
void apply();
@@ -121,6 +128,7 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
121128

122129
// background reference font
123130
QFont mRefFont;
131+
bool mDockMode;
124132
int mPreviewSize;
125133

126134
int mMinPixelLimit;

‎src/app/qgslabelingwidget.cpp

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
* (at your option) any later version. *
1313
* *
1414
***************************************************************************/
15+
16+
#include <QDialogButtonBox>
17+
#include <QDomElement>
18+
1519
#include "qgslabelingwidget.h"
1620

1721
#include "qgslabelengineconfigdialog.h"
@@ -31,14 +35,68 @@ QgsLabelingWidget::QgsLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canva
3135
connect( mEngineSettingsButton, SIGNAL( clicked() ), this, SLOT( showEngineConfigDialog() ) );
3236

3337
mLabelModeComboBox->setCurrentIndex( -1 );
38+
mLabelGui = new QgsLabelingGui( nullptr, mCanvas, nullptr, this );
39+
mStackedWidget->addWidget( mLabelGui );
3440

3541
connect( mLabelModeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( labelModeChanged( int ) ) );
42+
connect( mLabelGui, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
43+
setLayer( layer );
44+
}
45+
46+
void QgsLabelingWidget::resetSettings()
47+
{
48+
if ( mOldSettings )
49+
{
50+
mLayer->setLabeling( mOldSettings );
51+
if ( mOldSettings->type() == "simple" )
52+
{
53+
mOldPalSettings.writeToLayer( mLayer );
54+
}
55+
}
56+
setLayer( mLayer );
57+
}
58+
59+
60+
void QgsLabelingWidget::setLayer( QgsMapLayer* mapLayer )
61+
{
62+
if ( !mapLayer || mapLayer->type() != QgsMapLayer::VectorLayer )
63+
{
64+
setEnabled( false );
65+
return;
66+
}
67+
else
68+
{
69+
setEnabled( true );
70+
}
71+
72+
QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>( mapLayer );
73+
mLayer = layer;
74+
if ( mLayer->labeling() )
75+
{
76+
QDomDocument doc;
77+
QDomElement oldSettings = mLayer->labeling()->save( doc );
78+
mOldSettings = QgsAbstractVectorLayerLabeling::create( oldSettings );
79+
mOldPalSettings.readFromLayer( mLayer );
80+
}
81+
else
82+
mOldSettings = nullptr;
3683

3784
adaptToLayer();
3885
}
3986

87+
void QgsLabelingWidget::setDockMode( bool enabled )
88+
{
89+
mDockMode = enabled;
90+
mLabelGui->setDockMode( mDockMode );
91+
}
92+
4093
void QgsLabelingWidget::adaptToLayer()
4194
{
95+
if ( !mLayer )
96+
return;
97+
98+
QgsDebugMsg( QString( "Setting up for layer %1" ).arg( mLayer->name() ) );
99+
42100
mLabelModeComboBox->setCurrentIndex( -1 );
43101

44102
// pick the right mode of the layer
@@ -72,7 +130,7 @@ void QgsLabelingWidget::writeSettingsToLayer()
72130
}
73131
else
74132
{
75-
qobject_cast<QgsLabelingGui*>( mWidget )->writeSettingsToLayer();
133+
mLabelGui->writeSettingsToLayer();
76134
}
77135
}
78136

@@ -92,46 +150,32 @@ void QgsLabelingWidget::labelModeChanged( int index )
92150
if ( index < 0 )
93151
return;
94152

95-
if ( index != 2 )
153+
if ( index == 2 )
96154
{
97-
if ( QgsLabelingGui* widgetSimple = qobject_cast<QgsLabelingGui*>( mWidget ) )
98-
{
99-
// lighter variant - just change the mode of existing widget
100-
if ( index == 3 )
101-
widgetSimple->setLabelMode( QgsLabelingGui::ObstaclesOnly );
102-
else
103-
widgetSimple->setLabelMode( static_cast< QgsLabelingGui::LabelMode >( index ) );
104-
return;
105-
}
106-
}
107-
108-
// in general case we need to recreate the widget
155+
if ( mWidget )
156+
mStackedWidget->removeWidget( mWidget );
109157

110-
if ( mWidget )
111-
mStackedWidget->removeWidget( mWidget );
158+
delete mWidget;
159+
mWidget = nullptr;
112160

113-
delete mWidget;
114-
mWidget = nullptr;
115-
116-
if ( index == 2 )
117-
{
118-
mWidget = new QgsRuleBasedLabelingWidget( mLayer, mCanvas, this );
161+
QgsRuleBasedLabelingWidget* ruleWidget = new QgsRuleBasedLabelingWidget( mLayer, mCanvas, this, mDockMode );
162+
connect( ruleWidget, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
163+
mWidget = ruleWidget;
164+
mStackedWidget->addWidget( mWidget );
165+
mStackedWidget->setCurrentWidget( mWidget );
119166
}
120167
else
121168
{
122-
QgsLabelingGui* w = new QgsLabelingGui( mLayer, mCanvas, nullptr, this );
123169

124170
if ( index == 3 )
125-
w->setLabelMode( QgsLabelingGui::ObstaclesOnly );
171+
mLabelGui->setLabelMode( QgsLabelingGui::ObstaclesOnly );
126172
else
127-
w->setLabelMode( static_cast< QgsLabelingGui::LabelMode >( index ) );
173+
mLabelGui->setLabelMode( static_cast< QgsLabelingGui::LabelMode >( index ) );
128174

129-
w->init();
130-
mWidget = w;
175+
mLabelGui->setLayer( mLayer );
176+
mStackedWidget->setCurrentWidget( mLabelGui );
131177
}
132-
133-
mStackedWidget->addWidget( mWidget );
134-
mStackedWidget->setCurrentWidget( mWidget );
178+
emit widgetChanged();
135179
}
136180

137181
void QgsLabelingWidget::showEngineConfigDialog()

‎src/app/qgslabelingwidget.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
#include <QWidget>
55

66
#include <ui_qgslabelingwidget.h>
7+
#include <qgspallabeling.h>
78

89
class QgsLabelingGui;
910
class QgsMapCanvas;
1011
class QgsRuleBasedLabelingWidget;
12+
class QgsAbstractVectorLayerLabeling;
1113
class QgsVectorLayer;
14+
class QgsMapLayer;
1215

1316
/**
1417
* Master widget for configuration of labeling of a vector layer
@@ -20,6 +23,8 @@ class QgsLabelingWidget : public QWidget, private Ui::QgsLabelingWidget
2023
QgsLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent = nullptr );
2124

2225
public slots:
26+
void setLayer( QgsMapLayer *layer );
27+
void setDockMode( bool enabled );
2328
//! save config to layer
2429
void writeSettingsToLayer();
2530

@@ -29,6 +34,11 @@ class QgsLabelingWidget : public QWidget, private Ui::QgsLabelingWidget
2934
//! reload the settings shown in the dialog from the current layer
3035
void adaptToLayer();
3136

37+
void resetSettings();
38+
39+
signals:
40+
void widgetChanged();
41+
3242
protected slots:
3343
void labelModeChanged( int index );
3444
void showEngineConfigDialog();
@@ -37,7 +47,12 @@ class QgsLabelingWidget : public QWidget, private Ui::QgsLabelingWidget
3747
QgsVectorLayer* mLayer;
3848
QgsMapCanvas* mCanvas;
3949

50+
bool mDockMode;
51+
4052
QWidget* mWidget;
53+
QgsLabelingGui* mLabelGui;
54+
QgsAbstractVectorLayerLabeling* mOldSettings;
55+
QgsPalLayerSettings mOldPalSettings;
4156
};
4257

4358
#endif // QGSLABELINGWIDGET_H

‎src/app/qgsmapstylingwidget.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <QLabel>
2+
#include <QVBoxLayout>
3+
#include <QHBoxLayout>
4+
#include <QWidget>
5+
#include <QSizePolicy>
6+
7+
#include "qgsapplication.h"
8+
#include "qgslabelingwidget.h"
9+
#include "qgsmapstylingwidget.h"
10+
#include "qgsmapcanvas.h"
11+
#include "qgsmaplayer.h"
12+
13+
QgsMapStylingWidget::QgsMapStylingWidget( QgsMapCanvas* canvas, QWidget *parent ) :
14+
QWidget( parent ), mMapCanvas( canvas ), mBlockAutoApply( false ), mCurrentLayer( nullptr )
15+
{
16+
QBoxLayout* layout = new QVBoxLayout();
17+
layout->setContentsMargins( 0, 0, 0, 0 );
18+
this->setLayout( layout );
19+
20+
mStackedWidget = new QStackedWidget( this );
21+
mMapStyleTabs = new QTabWidget( this );
22+
mMapStyleTabs->setDocumentMode( true );
23+
mNotSupportedPage = mStackedWidget->addWidget( new QLabel( "Not supported currently" ) );
24+
mVectorPage = mStackedWidget->addWidget( mMapStyleTabs );
25+
26+
layout->addWidget( mStackedWidget );
27+
mButtonBox = new QDialogButtonBox( QDialogButtonBox::Reset | QDialogButtonBox::Apply );
28+
mLiveApplyCheck = new QCheckBox( "Live update" );
29+
mLiveApplyCheck->setChecked( true );
30+
31+
QHBoxLayout* bottomLayout = new QHBoxLayout( );
32+
bottomLayout->addWidget( mButtonBox );
33+
bottomLayout->addWidget( mLiveApplyCheck );
34+
layout->addLayout( bottomLayout );
35+
36+
mLabelingWidget = new QgsLabelingWidget( 0, mMapCanvas, this );
37+
mLabelingWidget->setDockMode( true );
38+
connect( mLabelingWidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
39+
40+
// Only labels for now but styles and diagrams will come later
41+
// int styleTabIndex = mMapStyleTabs->addTab( new QWidget(), QgsApplication::getThemeIcon( "propertyicons/symbology.png" ), "Styles" );
42+
mLabelTabIndex = mMapStyleTabs->addTab( mLabelingWidget, QgsApplication::getThemeIcon( "labelingSingle.svg" ), "Labeling" );
43+
// int diagramTabIndex = mMapStyleTabs->addTab( new QWidget(), QgsApplication::getThemeIcon( "propertyicons/diagram.png" ), "Diagrams" );
44+
// mMapStyleTabs->setTabEnabled( styleTabIndex, false );
45+
// mMapStyleTabs->setTabEnabled( diagramTabIndex, false );
46+
mMapStyleTabs->setCurrentIndex( mLabelTabIndex );
47+
48+
connect( mLiveApplyCheck, SIGNAL( toggled( bool ) ), mButtonBox->button( QDialogButtonBox::Apply ), SLOT( setDisabled( bool ) ) );
49+
50+
connect( mButtonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
51+
connect( mButtonBox->button( QDialogButtonBox::Reset ), SIGNAL( clicked() ), this, SLOT( resetSettings() ) );
52+
53+
mButtonBox->button( QDialogButtonBox::Apply )->setEnabled( false );
54+
mButtonBox->button( QDialogButtonBox::Reset )->setEnabled( false );
55+
56+
}
57+
58+
void QgsMapStylingWidget::setLayer( QgsMapLayer *layer )
59+
{
60+
if ( !layer )
61+
return;
62+
63+
mBlockAutoApply = true;
64+
65+
mCurrentLayer = layer;
66+
67+
if ( layer->type() == QgsMapLayer::VectorLayer )
68+
{
69+
mStackedWidget->setCurrentIndex( mVectorPage );
70+
// TODO Once there is support for more then just labels
71+
// we need to add a check for the just the current tab
72+
mMapStyleTabs->setCurrentIndex( mLabelTabIndex );
73+
mLabelingWidget->setLayer( layer );
74+
}
75+
else if ( layer->type() == QgsMapLayer::RasterLayer )
76+
{
77+
mStackedWidget->setCurrentIndex( mNotSupportedPage );
78+
}
79+
else if ( layer->type() == QgsMapLayer::PluginLayer )
80+
{
81+
mStackedWidget->setCurrentIndex( mNotSupportedPage );
82+
}
83+
84+
mBlockAutoApply = false;
85+
86+
mButtonBox->button( QDialogButtonBox::Reset )->setEnabled( false );
87+
}
88+
89+
void QgsMapStylingWidget::apply()
90+
{
91+
if ( mStackedWidget->currentIndex() == mVectorPage &&
92+
mMapStyleTabs->currentIndex() == mLabelTabIndex )
93+
{
94+
mLabelingWidget->apply();
95+
mButtonBox->button( QDialogButtonBox::Reset )->setEnabled( true );
96+
emit styleChanged( mCurrentLayer );
97+
}
98+
}
99+
100+
void QgsMapStylingWidget::autoApply()
101+
{
102+
if ( mLiveApplyCheck->isChecked() && !mBlockAutoApply )
103+
apply();
104+
}
105+
106+
void QgsMapStylingWidget::resetSettings()
107+
{
108+
if ( mStackedWidget->currentIndex() == mVectorPage &&
109+
mMapStyleTabs->currentIndex() == mLabelTabIndex )
110+
{
111+
mLabelingWidget->resetSettings();
112+
}
113+
}

‎src/app/qgsmapstylingwidget.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef QGSMAPSTYLESDOCK_H
2+
#define QGSMAPSTYLESDOCK_H
3+
4+
#include <QWidget>
5+
#include <QTabWidget>
6+
#include <QStackedWidget>
7+
#include <QDialogButtonBox>
8+
#include <QCheckBox>
9+
10+
class QgsLabelingWidget;
11+
class QgsMapLayer;
12+
class QgsMapCanvas;
13+
14+
15+
class APP_EXPORT QgsMapStylingWidget : public QWidget
16+
{
17+
Q_OBJECT
18+
public:
19+
explicit QgsMapStylingWidget( QgsMapCanvas *canvas, QWidget *parent = 0 );
20+
QgsMapLayer* layer() { return mCurrentLayer; }
21+
22+
signals:
23+
void styleChanged( QgsMapLayer* layer );
24+
25+
public slots:
26+
void setLayer( QgsMapLayer* layer );
27+
void apply();
28+
void autoApply();
29+
void resetSettings();
30+
31+
private:
32+
int mNotSupportedPage;
33+
int mVectorPage;
34+
int mLabelTabIndex;
35+
QgsMapCanvas* mMapCanvas;
36+
bool mBlockAutoApply;
37+
QgsMapLayer* mCurrentLayer;
38+
QStackedWidget* mStackedWidget;
39+
QTabWidget *mMapStyleTabs;
40+
QgsLabelingWidget *mLabelingWidget;
41+
QDialogButtonBox* mButtonBox;
42+
QCheckBox* mLiveApplyCheck;
43+
44+
};
45+
46+
#endif // QGSMAPSTYLESDOCK_H

‎src/app/qgsrulebasedlabelingwidget.cpp

Lines changed: 108 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
#include <QClipboard>
2525
#include <QMessageBox>
2626

27-
QgsRuleBasedLabelingWidget::QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent )
27+
QgsRuleBasedLabelingWidget::QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent, bool dockMode )
2828
: QWidget( parent )
2929
, mLayer( layer )
3030
, mCanvas( canvas )
3131
, mRootRule( nullptr )
3232
, mModel( nullptr )
33+
, mRuleProps( nullptr )
34+
, mDockMode( dockMode )
3335
{
3436
setupUi( this );
3537

@@ -76,6 +78,11 @@ QgsRuleBasedLabelingWidget::~QgsRuleBasedLabelingWidget()
7678
delete mRootRule;
7779
}
7880

81+
void QgsRuleBasedLabelingWidget::setDockMode( bool enabled )
82+
{
83+
mDockMode = enabled;
84+
}
85+
7986
void QgsRuleBasedLabelingWidget::writeSettingsToLayer()
8087
{
8188
// also clear old-style labeling config
@@ -86,31 +93,83 @@ void QgsRuleBasedLabelingWidget::writeSettingsToLayer()
8693

8794
void QgsRuleBasedLabelingWidget::addRule()
8895
{
96+
if ( mRuleProps )
97+
mStackedWidget->removeWidget( mRuleProps );
98+
99+
delete mRuleProps;
100+
mRuleProps = nullptr;
101+
102+
// TODO Delete rule
89103
QgsRuleBasedLabeling::Rule* newrule = new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings );
104+
mRuleProps = new QgsLabelingRulePropsDialog( newrule, mLayer, this, mCanvas, mDockMode );
105+
mRuleProps->setCurrentMode( QgsLabelingRulePropsDialog::Adding );
90106

91-
QgsLabelingRulePropsDialog dlg( newrule, mLayer, this, mCanvas );
92-
if ( dlg.exec() )
107+
mStackedWidget->addWidget( mRuleProps );
108+
mStackedWidget->setCurrentWidget( mRuleProps );
109+
110+
connect( mRuleProps, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
111+
connect( mRuleProps, SIGNAL( accepted() ), this, SLOT( saveRule() ) );
112+
connect( mRuleProps, SIGNAL( rejected() ), this, SLOT( rejectRule() ) );
113+
addNewRule( newrule );
114+
}
115+
116+
void QgsRuleBasedLabelingWidget::saveRuleEdit()
117+
{
118+
QModelIndex index = viewRules->selectionModel()->currentIndex();
119+
mModel->updateRule( index.parent(), index.row() );
120+
if ( mRuleProps )
121+
mStackedWidget->removeWidget( mRuleProps );
122+
123+
delete mRuleProps;
124+
mRuleProps = nullptr;
125+
mStackedWidget->setCurrentIndex( 0 );
126+
emit widgetChanged();
127+
}
128+
129+
void QgsRuleBasedLabelingWidget::saveRule()
130+
{
131+
if ( mRuleProps )
132+
mStackedWidget->removeWidget( mRuleProps );
133+
134+
delete mRuleProps;
135+
mRuleProps = nullptr;
136+
mStackedWidget->setCurrentIndex( 0 );
137+
emit widgetChanged();
138+
}
139+
140+
void QgsRuleBasedLabelingWidget::addNewRule( QgsRuleBasedLabeling::Rule* newrule )
141+
{
142+
if ( currentRule() )
93143
{
94-
QgsRuleBasedLabeling::Rule* current = currentRule();
95-
if ( current )
96-
{
97-
// add after this rule
98-
QModelIndex currentIndex = viewRules->selectionModel()->currentIndex();
99-
mModel->insertRule( currentIndex.parent(), currentIndex.row() + 1, newrule );
100-
}
101-
else
102-
{
103-
// append to root rule
104-
int rows = mModel->rowCount();
105-
mModel->insertRule( QModelIndex(), rows, newrule );
106-
}
144+
// add after this rule
145+
QModelIndex currentIndex = viewRules->selectionModel()->currentIndex();
146+
mModel->insertRule( currentIndex.parent(), currentIndex.row() + 1, newrule );
147+
viewRules->selectionModel()->select( mModel->index( currentIndex.row() + 1, 0 ), QItemSelectionModel::ClearAndSelect );
107148
}
108149
else
109150
{
110-
delete newrule;
151+
// append to root rule
152+
int rows = mModel->rowCount();
153+
mModel->insertRule( QModelIndex(), rows, newrule );
154+
viewRules->selectionModel()->select( mModel->index( rows, 0 ), QItemSelectionModel::ClearAndSelect );
111155
}
112156
}
113157

158+
void QgsRuleBasedLabelingWidget::rejectRule()
159+
{
160+
if ( mRuleProps->currentMode() == QgsLabelingRulePropsDialog::Adding )
161+
removeRule();
162+
163+
mStackedWidget->setCurrentIndex( 0 );
164+
165+
if ( mRuleProps )
166+
mStackedWidget->removeWidget( mRuleProps );
167+
168+
delete mRuleProps;
169+
mRuleProps = nullptr;
170+
emit widgetChanged();
171+
}
172+
114173
void QgsRuleBasedLabelingWidget::editRule()
115174
{
116175
editRule( viewRules->selectionModel()->currentIndex() );
@@ -120,14 +179,24 @@ void QgsRuleBasedLabelingWidget::editRule( const QModelIndex& index )
120179
{
121180
if ( !index.isValid() )
122181
return;
182+
183+
if ( mRuleProps )
184+
mStackedWidget->removeWidget( mRuleProps );
185+
186+
delete mRuleProps;
187+
mRuleProps = nullptr;
188+
123189
QgsRuleBasedLabeling::Rule* rule = mModel->ruleForIndex( index );
190+
mRuleProps = new QgsLabelingRulePropsDialog( rule, mLayer, this, mCanvas, mDockMode );
191+
mRuleProps->setCurrentMode( QgsLabelingRulePropsDialog::Editing );
124192

125-
QgsLabelingRulePropsDialog dlg( rule, mLayer, this, mCanvas );
126-
if ( dlg.exec() )
127-
{
128-
// model should know about the change and emit dataChanged signal for the view
129-
mModel->updateRule( index.parent(), index.row() );
130-
}
193+
connect( mRuleProps, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
194+
195+
mStackedWidget->addWidget( mRuleProps );
196+
mStackedWidget->setCurrentWidget( mRuleProps );
197+
198+
connect( mRuleProps, SIGNAL( accepted() ), this, SLOT( saveRuleEdit() ) );
199+
connect( mRuleProps, SIGNAL( rejected() ), this, SLOT( rejectRule() ) );
131200
}
132201

133202
void QgsRuleBasedLabelingWidget::removeRule()
@@ -142,6 +211,7 @@ void QgsRuleBasedLabelingWidget::removeRule()
142211
}
143212
// make sure that the selection is gone
144213
viewRules->selectionModel()->clear();
214+
emit widgetChanged();
145215
}
146216

147217
void QgsRuleBasedLabelingWidget::copy()
@@ -154,6 +224,7 @@ void QgsRuleBasedLabelingWidget::copy()
154224

155225
QMimeData* mime = mModel->mimeData( indexlist );
156226
QApplication::clipboard()->setMimeData( mime );
227+
emit widgetChanged();
157228
}
158229

159230
void QgsRuleBasedLabelingWidget::paste()
@@ -166,6 +237,7 @@ void QgsRuleBasedLabelingWidget::paste()
166237
else
167238
index = indexlist.first();
168239
mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() );
240+
emit widgetChanged();
169241
}
170242

171243
QgsRuleBasedLabeling::Rule* QgsRuleBasedLabelingWidget::currentRule()
@@ -550,8 +622,8 @@ void QgsRuleBasedLabelingModel::updateRule( const QModelIndex& parent, int row )
550622

551623
/////////
552624

553-
QgsLabelingRulePropsDialog::QgsLabelingRulePropsDialog( QgsRuleBasedLabeling::Rule* rule, QgsVectorLayer* layer, QWidget* parent, QgsMapCanvas* mapCanvas )
554-
: QDialog( parent ), mRule( rule ), mLayer( layer ), mLabelingGui( nullptr ), mSettings( nullptr ), mMapCanvas( mapCanvas )
625+
QgsLabelingRulePropsDialog::QgsLabelingRulePropsDialog( QgsRuleBasedLabeling::Rule* rule, QgsVectorLayer* layer, QWidget* parent, QgsMapCanvas* mapCanvas, bool dockMode )
626+
: QDialog( parent ), mRule( rule ), mLayer( layer ), mLabelingGui( nullptr ), mSettings( nullptr ), mMapCanvas( mapCanvas ), mDockMode( dockMode )
555627
{
556628
setupUi( this );
557629
#ifdef Q_OS_MAC
@@ -588,17 +660,21 @@ QgsLabelingRulePropsDialog::QgsLabelingRulePropsDialog( QgsRuleBasedLabeling::Ru
588660
mSettings = new QgsPalLayerSettings;
589661
}
590662

591-
mLabelingGui = new QgsLabelingGui( mLayer, mMapCanvas, mSettings, this );
663+
mLabelingGui = new QgsLabelingGui( nullptr, mMapCanvas, mSettings, this );
664+
mLabelingGui->setDockMode( mDockMode );
592665
mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
593666
QVBoxLayout* l = new QVBoxLayout;
594667
l->addWidget( mLabelingGui );
595668
groupSettings->setLayout( l );
596669

597670
mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
598-
mLabelingGui->init();
671+
mLabelingGui->setLayer( mLayer );
599672

600673
connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) );
601674
connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) );
675+
connect( editFilter, SIGNAL( textEdited( QString ) ), this, SIGNAL( widgetChanged() ) );
676+
connect( mLabelingGui, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
677+
connect( this, SIGNAL( widgetChanged() ), this, SLOT( updateRule() ) );
602678

603679
QSettings settings;
604680
restoreGeometry( settings.value( "/Windows/QgsLabelingRulePropsDialog/geometry" ).toByteArray() );
@@ -686,14 +762,18 @@ void QgsLabelingRulePropsDialog::buildExpression()
686762
editFilter->setText( dlg.expressionText() );
687763
}
688764

689-
void QgsLabelingRulePropsDialog::accept()
765+
void QgsLabelingRulePropsDialog::updateRule()
690766
{
691767
mRule->setFilterExpression( editFilter->text() );
692768
mRule->setDescription( editDescription->text() );
693769
// caution: rule uses scale denom, scale widget uses true scales
694770
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
695771
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
696772
mRule->setSettings( groupSettings->isChecked() ? new QgsPalLayerSettings( mLabelingGui->layerSettings() ) : nullptr );
773+
}
697774

775+
void QgsLabelingRulePropsDialog::accept()
776+
{
777+
updateRule();
698778
QDialog::accept();
699779
}

‎src/app/qgsrulebasedlabelingwidget.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,27 +72,37 @@ class APP_EXPORT QgsRuleBasedLabelingModel : public QAbstractItemModel
7272
};
7373

7474

75+
class QgsLabelingRulePropsDialog;
76+
7577

7678
class QgsRuleBasedLabelingWidget : public QWidget, private Ui::QgsRuleBasedLabelingWidget
7779
{
7880
Q_OBJECT
7981
public:
80-
QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent = nullptr );
82+
QgsRuleBasedLabelingWidget( QgsVectorLayer* layer, QgsMapCanvas* canvas, QWidget* parent = nullptr, bool dockMode = false );
8183
~QgsRuleBasedLabelingWidget();
8284

8385
//! save config to layer
8486
void writeSettingsToLayer();
87+
void setDockMode( bool enabled );
8588

8689
signals:
90+
void widgetChanged();
8791

8892
protected slots:
93+
void saveRuleEdit();
8994
void addRule();
95+
void saveRule();
96+
void rejectRule();
9097
void editRule();
9198
void editRule( const QModelIndex& index );
9299
void removeRule();
93100
void copy();
94101
void paste();
95102

103+
private:
104+
void addNewRule( QgsRuleBasedLabeling::Rule* newrule );
105+
96106
protected:
97107
QgsRuleBasedLabeling::Rule* currentRule();
98108

@@ -102,10 +112,12 @@ class QgsRuleBasedLabelingWidget : public QWidget, private Ui::QgsRuleBasedLabel
102112

103113
QgsRuleBasedLabeling::Rule* mRootRule;
104114
QgsRuleBasedLabelingModel* mModel;
115+
QgsLabelingRulePropsDialog* mRuleProps;
105116

106117
QAction* mCopyAction;
107118
QAction* mPasteAction;
108119
QAction* mDeleteAction;
120+
bool mDockMode;
109121
};
110122

111123

@@ -120,14 +132,29 @@ class APP_EXPORT QgsLabelingRulePropsDialog : public QDialog, private Ui::QgsLab
120132
Q_OBJECT
121133

122134
public:
123-
QgsLabelingRulePropsDialog( QgsRuleBasedLabeling::Rule* rule, QgsVectorLayer* layer, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
135+
enum Mode
136+
{
137+
Adding,
138+
Editing
139+
};
140+
141+
QgsLabelingRulePropsDialog( QgsRuleBasedLabeling::Rule* rule, QgsVectorLayer* layer,
142+
QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr,
143+
bool dockMode = false );
124144
~QgsLabelingRulePropsDialog();
125145

126146
QgsRuleBasedLabeling::Rule* rule() { return mRule; }
127147

148+
Mode currentMode() { return mCurrentMode; }
149+
void setCurrentMode( Mode currentMode ) { mCurrentMode = currentMode; }
150+
151+
signals:
152+
void widgetChanged();
153+
128154
public slots:
129155
void testFilter();
130156
void buildExpression();
157+
void updateRule();
131158
void accept() override;
132159

133160
protected:
@@ -138,6 +165,8 @@ class APP_EXPORT QgsLabelingRulePropsDialog : public QDialog, private Ui::QgsLab
138165
QgsPalLayerSettings* mSettings; // a clone of original settings
139166

140167
QgsMapCanvas* mMapCanvas;
168+
bool mDockMode;
169+
Mode mCurrentMode;
141170
};
142171

143172

‎src/gui/qgisgui.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,5 +200,4 @@ namespace QgisGui
200200
return QFontDialog::getFont( &ok, initial, nullptr, title );
201201
#endif
202202
}
203-
204203
} // end of QgisGui namespace

‎src/gui/qgsfieldexpressionwidget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class GUI_EXPORT QgsFieldExpressionWidget : public QWidget
127127
//! convenience slot to connect QgsMapLayerComboBox layer signal
128128
void setLayer( QgsMapLayer* layer );
129129

130+
//! sets the current row in the widget
131+
void setRow( int row ) { mCombo->setCurrentIndex( row ); }
132+
130133
//! sets the current field or expression in the widget
131134
void setField( const QString &fieldName );
132135

‎src/ui/qgslabelingguibase.ui

Lines changed: 330 additions & 619 deletions
Large diffs are not rendered by default.

‎src/ui/qgslabelingrulepropsdialog.ui

Lines changed: 103 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,96 +14,124 @@
1414
<string>Rule properties</string>
1515
</property>
1616
<layout class="QVBoxLayout" name="verticalLayout">
17+
<property name="margin">
18+
<number>0</number>
19+
</property>
1720
<item>
18-
<layout class="QFormLayout" name="formLayout">
19-
<property name="fieldGrowthPolicy">
20-
<enum>QFormLayout::ExpandingFieldsGrow</enum>
21+
<widget class="QScrollArea" name="scrollArea">
22+
<property name="frameShape">
23+
<enum>QFrame::NoFrame</enum>
2124
</property>
22-
<item row="0" column="0">
23-
<widget class="QLabel" name="label_1">
24-
<property name="text">
25-
<string>Description</string>
26-
</property>
27-
</widget>
28-
</item>
29-
<item row="0" column="1">
30-
<widget class="QLineEdit" name="editDescription"/>
31-
</item>
32-
<item row="1" column="0">
33-
<widget class="QLabel" name="label_5">
34-
<property name="text">
35-
<string>Filter</string>
25+
<property name="widgetResizable">
26+
<bool>true</bool>
27+
</property>
28+
<widget class="QWidget" name="scrollAreaWidgetContents">
29+
<property name="geometry">
30+
<rect>
31+
<x>0</x>
32+
<y>0</y>
33+
<width>666</width>
34+
<height>540</height>
35+
</rect>
36+
</property>
37+
<layout class="QVBoxLayout" name="verticalLayout_2">
38+
<property name="margin">
39+
<number>0</number>
3640
</property>
37-
</widget>
38-
</item>
39-
<item row="1" column="1">
40-
<layout class="QHBoxLayout" name="horizontalLayout">
4141
<item>
42-
<widget class="QLineEdit" name="editFilter"/>
42+
<layout class="QFormLayout" name="formLayout">
43+
<property name="fieldGrowthPolicy">
44+
<enum>QFormLayout::ExpandingFieldsGrow</enum>
45+
</property>
46+
<item row="0" column="0">
47+
<widget class="QLabel" name="label_1">
48+
<property name="text">
49+
<string>Description</string>
50+
</property>
51+
</widget>
52+
</item>
53+
<item row="0" column="1">
54+
<widget class="QLineEdit" name="editDescription"/>
55+
</item>
56+
<item row="1" column="0">
57+
<widget class="QLabel" name="label_5">
58+
<property name="text">
59+
<string>Filter</string>
60+
</property>
61+
</widget>
62+
</item>
63+
<item row="1" column="1">
64+
<layout class="QHBoxLayout" name="horizontalLayout">
65+
<item>
66+
<widget class="QLineEdit" name="editFilter"/>
67+
</item>
68+
<item>
69+
<widget class="QPushButton" name="btnExpressionBuilder">
70+
<property name="sizePolicy">
71+
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
72+
<horstretch>0</horstretch>
73+
<verstretch>0</verstretch>
74+
</sizepolicy>
75+
</property>
76+
<property name="text">
77+
<string>...</string>
78+
</property>
79+
</widget>
80+
</item>
81+
<item>
82+
<widget class="QPushButton" name="btnTestFilter">
83+
<property name="text">
84+
<string>Test</string>
85+
</property>
86+
</widget>
87+
</item>
88+
</layout>
89+
</item>
90+
</layout>
4391
</item>
4492
<item>
45-
<widget class="QPushButton" name="btnExpressionBuilder">
93+
<widget class="QGroupBox" name="groupScale">
94+
<property name="title">
95+
<string>Scale range</string>
96+
</property>
97+
<property name="checkable">
98+
<bool>true</bool>
99+
</property>
100+
<property name="checked">
101+
<bool>false</bool>
102+
</property>
103+
<layout class="QHBoxLayout" name="horizontalLayout_2">
104+
<item>
105+
<widget class="QgsScaleRangeWidget" name="mScaleRangeWidget">
106+
<property name="toolTip">
107+
<string/>
108+
</property>
109+
<property name="whatsThis">
110+
<string/>
111+
</property>
112+
</widget>
113+
</item>
114+
</layout>
115+
</widget>
116+
</item>
117+
<item>
118+
<widget class="QGroupBox" name="groupSettings">
46119
<property name="sizePolicy">
47-
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
120+
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
48121
<horstretch>0</horstretch>
49122
<verstretch>0</verstretch>
50123
</sizepolicy>
51124
</property>
52-
<property name="text">
53-
<string>...</string>
125+
<property name="title">
126+
<string>Labels</string>
54127
</property>
55-
</widget>
56-
</item>
57-
<item>
58-
<widget class="QPushButton" name="btnTestFilter">
59-
<property name="text">
60-
<string>Test</string>
128+
<property name="checkable">
129+
<bool>true</bool>
61130
</property>
62131
</widget>
63132
</item>
64133
</layout>
65-
</item>
66-
</layout>
67-
</item>
68-
<item>
69-
<widget class="QGroupBox" name="groupScale">
70-
<property name="title">
71-
<string>Scale range</string>
72-
</property>
73-
<property name="checkable">
74-
<bool>true</bool>
75-
</property>
76-
<property name="checked">
77-
<bool>false</bool>
78-
</property>
79-
<layout class="QHBoxLayout" name="horizontalLayout_2">
80-
<item>
81-
<widget class="QgsScaleRangeWidget" name="mScaleRangeWidget" native="true">
82-
<property name="toolTip">
83-
<string/>
84-
</property>
85-
<property name="whatsThis">
86-
<string/>
87-
</property>
88-
</widget>
89-
</item>
90-
</layout>
91-
</widget>
92-
</item>
93-
<item>
94-
<widget class="QGroupBox" name="groupSettings">
95-
<property name="sizePolicy">
96-
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
97-
<horstretch>0</horstretch>
98-
<verstretch>0</verstretch>
99-
</sizepolicy>
100-
</property>
101-
<property name="title">
102-
<string>Labels</string>
103-
</property>
104-
<property name="checkable">
105-
<bool>true</bool>
106-
</property>
134+
</widget>
107135
</widget>
108136
</item>
109137
<item>
@@ -112,7 +140,7 @@
112140
<enum>Qt::Horizontal</enum>
113141
</property>
114142
<property name="standardButtons">
115-
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
143+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
116144
</property>
117145
</widget>
118146
</item>
@@ -130,8 +158,6 @@
130158
<tabstop>editFilter</tabstop>
131159
<tabstop>btnExpressionBuilder</tabstop>
132160
<tabstop>btnTestFilter</tabstop>
133-
<tabstop>groupScale</tabstop>
134-
<tabstop>groupSettings</tabstop>
135161
<tabstop>buttonBox</tabstop>
136162
</tabstops>
137163
<resources/>

‎src/ui/qgslabelingwidget.ui

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@
9797
<item>
9898
<widget class="QStackedWidget" name="mStackedWidget"/>
9999
</item>
100+
<item>
101+
<layout class="QHBoxLayout" name="horizontalLayout_2">
102+
<property name="spacing">
103+
<number>12</number>
104+
</property>
105+
<property name="topMargin">
106+
<number>0</number>
107+
</property>
108+
</layout>
109+
</item>
100110
</layout>
101111
</widget>
102112
<resources>

‎src/ui/qgsrulebasedlabelingwidget.ui

Lines changed: 99 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -6,100 +6,114 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>400</width>
10-
<height>300</height>
9+
<width>457</width>
10+
<height>372</height>
1111
</rect>
1212
</property>
1313
<layout class="QVBoxLayout" name="verticalLayout">
1414
<property name="margin">
1515
<number>0</number>
1616
</property>
1717
<item>
18-
<widget class="QTreeView" name="viewRules">
19-
<property name="contextMenuPolicy">
20-
<enum>Qt::ActionsContextMenu</enum>
18+
<widget class="QStackedWidget" name="mStackedWidget">
19+
<property name="currentIndex">
20+
<number>0</number>
2121
</property>
22-
<property name="acceptDrops">
23-
<bool>true</bool>
24-
</property>
25-
<property name="editTriggers">
26-
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
27-
</property>
28-
<property name="dragEnabled">
29-
<bool>true</bool>
30-
</property>
31-
<property name="dragDropMode">
32-
<enum>QAbstractItemView::InternalMove</enum>
33-
</property>
34-
<property name="selectionMode">
35-
<enum>QAbstractItemView::ExtendedSelection</enum>
36-
</property>
37-
<property name="allColumnsShowFocus">
38-
<bool>true</bool>
39-
</property>
40-
<attribute name="headerMinimumSectionSize">
41-
<number>100</number>
42-
</attribute>
43-
</widget>
44-
</item>
45-
<item>
46-
<layout class="QHBoxLayout" name="horizontalLayout">
47-
<item>
48-
<widget class="QPushButton" name="btnAddRule">
49-
<property name="toolTip">
50-
<string>Add rule</string>
51-
</property>
52-
<property name="text">
53-
<string/>
22+
<widget class="QWidget" name="rulesPage">
23+
<layout class="QVBoxLayout" name="verticalLayout_2">
24+
<property name="margin">
25+
<number>0</number>
5426
</property>
55-
<property name="icon">
56-
<iconset resource="../../images/images.qrc">
57-
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
58-
</property>
59-
</widget>
60-
</item>
61-
<item>
62-
<widget class="QPushButton" name="btnEditRule">
63-
<property name="toolTip">
64-
<string>Edit rule</string>
65-
</property>
66-
<property name="text">
67-
<string/>
68-
</property>
69-
<property name="icon">
70-
<iconset resource="../../images/images.qrc">
71-
<normaloff>:/images/themes/default/symbologyEdit.png</normaloff>:/images/themes/default/symbologyEdit.png</iconset>
72-
</property>
73-
</widget>
74-
</item>
75-
<item>
76-
<widget class="QPushButton" name="btnRemoveRule">
77-
<property name="toolTip">
78-
<string>Remove rule</string>
79-
</property>
80-
<property name="text">
81-
<string/>
82-
</property>
83-
<property name="icon">
84-
<iconset resource="../../images/images.qrc">
85-
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
86-
</property>
87-
</widget>
88-
</item>
89-
<item>
90-
<spacer name="horizontalSpacer">
91-
<property name="orientation">
92-
<enum>Qt::Horizontal</enum>
93-
</property>
94-
<property name="sizeHint" stdset="0">
95-
<size>
96-
<width>40</width>
97-
<height>20</height>
98-
</size>
99-
</property>
100-
</spacer>
101-
</item>
102-
</layout>
27+
<item>
28+
<widget class="QTreeView" name="viewRules">
29+
<property name="contextMenuPolicy">
30+
<enum>Qt::ActionsContextMenu</enum>
31+
</property>
32+
<property name="acceptDrops">
33+
<bool>true</bool>
34+
</property>
35+
<property name="editTriggers">
36+
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
37+
</property>
38+
<property name="dragEnabled">
39+
<bool>true</bool>
40+
</property>
41+
<property name="dragDropMode">
42+
<enum>QAbstractItemView::InternalMove</enum>
43+
</property>
44+
<property name="selectionMode">
45+
<enum>QAbstractItemView::ExtendedSelection</enum>
46+
</property>
47+
<property name="allColumnsShowFocus">
48+
<bool>true</bool>
49+
</property>
50+
<attribute name="headerMinimumSectionSize">
51+
<number>100</number>
52+
</attribute>
53+
</widget>
54+
</item>
55+
<item>
56+
<layout class="QHBoxLayout" name="horizontalLayout">
57+
<item>
58+
<widget class="QPushButton" name="btnAddRule">
59+
<property name="toolTip">
60+
<string>Add rule</string>
61+
</property>
62+
<property name="text">
63+
<string/>
64+
</property>
65+
<property name="icon">
66+
<iconset resource="../../images/images.qrc">
67+
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
68+
</property>
69+
</widget>
70+
</item>
71+
<item>
72+
<widget class="QPushButton" name="btnEditRule">
73+
<property name="toolTip">
74+
<string>Edit rule</string>
75+
</property>
76+
<property name="text">
77+
<string/>
78+
</property>
79+
<property name="icon">
80+
<iconset resource="../../images/images.qrc">
81+
<normaloff>:/images/themes/default/symbologyEdit.png</normaloff>:/images/themes/default/symbologyEdit.png</iconset>
82+
</property>
83+
</widget>
84+
</item>
85+
<item>
86+
<widget class="QPushButton" name="btnRemoveRule">
87+
<property name="toolTip">
88+
<string>Remove rule</string>
89+
</property>
90+
<property name="text">
91+
<string/>
92+
</property>
93+
<property name="icon">
94+
<iconset resource="../../images/images.qrc">
95+
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
96+
</property>
97+
</widget>
98+
</item>
99+
<item>
100+
<spacer name="horizontalSpacer">
101+
<property name="orientation">
102+
<enum>Qt::Horizontal</enum>
103+
</property>
104+
<property name="sizeHint" stdset="0">
105+
<size>
106+
<width>40</width>
107+
<height>20</height>
108+
</size>
109+
</property>
110+
</spacer>
111+
</item>
112+
</layout>
113+
</item>
114+
</layout>
115+
</widget>
116+
</widget>
103117
</item>
104118
</layout>
105119
</widget>

0 commit comments

Comments
 (0)