Skip to content

Commit

Permalink
Avoid style dock flashing when editing layers
Browse files Browse the repository at this point in the history
Also prevent a lot of duplicate style dock updates, and fix
the style dock losing connection to layer style changes
  • Loading branch information
nyalldawson committed Jun 27, 2016
1 parent df579a5 commit c3c5c43
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 11 deletions.
17 changes: 16 additions & 1 deletion python/core/qgsmaplayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,11 @@ class QgsMapLayer : QObject
/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const;

/** Triggers an emission of the styleChanged() signal.
* @note added in QGIS 2.16
*/
void emitStyleChanged();

signals:

//! @deprecated in 2.4 - not emitted anymore
Expand Down Expand Up @@ -649,9 +654,19 @@ class QgsMapLayer : QObject
/** Signal emitted when the blend mode is changed, through QgsMapLayer::setBlendMode() */
void blendModeChanged( QPainter::CompositionMode blendMode );

/** Signal emitted when renderer is changed */
/** Signal emitted when renderer is changed.
* @see styleChanged()
*/
void rendererChanged();

/** Signal emitted whenever a change affects the layer's style. Ie this may be triggered
* by renderer changes, label style changes, or other style changes such as blend
* mode or layer opacity changes.
* @note added in QGIS 2.16
* @see rendererChanged()
*/
void styleChanged();

/**
* Signal emitted when legend of the layer has changed
* @note added in 2.6
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11345,10 +11345,14 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
vlp->addPropertiesPageFactory( factory );
}

mMapStyleWidget->blockUpdates( true );
if ( vlp->exec() )
{
activateDeactivateLayerRelatedActions( ml );
mMapStyleWidget->updateCurrentWidgetLayer();
}
mMapStyleWidget->blockUpdates( false );

delete vlp; // delete since dialog cannot be reused without updating code
}
else if ( ml->type() == QgsMapLayer::PluginLayer )
Expand Down
11 changes: 10 additions & 1 deletion src/app/qgsapplayertreeviewmenuprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ void QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor( const QColor& color
return;

QString layerId = action->property( "layerId" ).toString();
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
if ( !layer )
return;

Expand Down Expand Up @@ -545,6 +545,7 @@ void QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor( const QColor& color
}

layer->triggerRepaint();
layer->emitStyleChanged();
mView->refreshLayerSymbology( layer->id() );
}

Expand Down Expand Up @@ -573,6 +574,10 @@ void QgsAppLayerTreeViewMenuProvider::editSymbolLegendNodeSymbol()
if ( dlg.exec() )
{
node->setSymbol( symbol.take() );
if ( vlayer )
{
vlayer->emitStyleChanged();
}
}
}

Expand All @@ -596,4 +601,8 @@ void QgsAppLayerTreeViewMenuProvider::setSymbolLegendNodeColor( const QColor &co
QgsSymbolV2* newSymbol = originalSymbol->clone();
newSymbol->setColor( color );
node->setSymbol( newSymbol );
if ( QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) ) )
{
layer->emitStyleChanged();
}
}
35 changes: 30 additions & 5 deletions src/app/qgslayerstylingwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,37 @@ void QgsLayerStylingWidget::setPageFactories( QList<QgsLayerStylingPanelFactory
mPageFactories.append( mStyleManagerFactory );
}

void QgsLayerStylingWidget::blockUpdates( bool blocked )
{
if ( !mCurrentLayer )
return;

if ( blocked )
{
disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}
else
{
connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}
}

void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
{
if ( layer == mCurrentLayer )
return;

if ( mCurrentLayer )
{
disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}

if ( !layer || !layer->isSpatial() )
{
mLayerCombo->setLayer( nullptr );
mStackedWidget->setCurrentIndex( mNotSupportedPage );
mLastStyleXml.clear();
mCurrentLayer = nullptr;
return;
}

Expand All @@ -112,9 +136,10 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
}

mCurrentLayer = layer;
connect( mCurrentLayer, SIGNAL( repaintRequested() ), this, SLOT( updateCurrentWidgetLayer() ) );
connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );

int lastPage = mOptionsListWidget->currentIndex().row();
mOptionsListWidget->blockSignals( true );
mOptionsListWidget->clear();
mUserPages.clear();
if ( layer->type() == QgsMapLayer::VectorLayer )
Expand All @@ -140,6 +165,7 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
}
}
mOptionsListWidget->addItem( new QListWidgetItem( QgsApplication::getThemeIcon( "mActionHistory.svg" ), "" ) );
mOptionsListWidget->blockSignals( false );

if ( sameLayerType )
{
Expand All @@ -164,7 +190,7 @@ void QgsLayerStylingWidget::apply()
if ( !mCurrentLayer )
return;

disconnect( mCurrentLayer, SIGNAL( repaintRequested() ), this, SLOT( updateCurrentWidgetLayer() ) );
disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );

QString undoName = "Style Change";

Expand Down Expand Up @@ -213,7 +239,7 @@ void QgsLayerStylingWidget::apply()
mMapCanvas->clearCache();
mMapCanvas->refresh();
}
disconnect( mCurrentLayer, SIGNAL( repaintRequested() ), this, SLOT( updateCurrentWidgetLayer() ) );
connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}

void QgsLayerStylingWidget::autoApply()
Expand Down Expand Up @@ -374,8 +400,7 @@ void QgsLayerStylingWidget::layerAboutToBeRemoved( QgsMapLayer* layer )
if ( layer == mCurrentLayer )
{
mAutoApplyTimer->stop();
mStackedWidget->setCurrentIndex( mNotSupportedPage );
mCurrentLayer = nullptr;
setLayer( nullptr );
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/app/qgslayerstylingwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty

void setPageFactories( QList<QgsLayerStylingPanelFactory*> factories );

/** Sets whether updates of the styling widget are blocked. This can be called to prevent
* the widget being refreshed multiple times when a batch of layer style changes are
* about to be applied
* @param blocked set to true to block updates, or false to re-allow updates
*/
void blockUpdates( bool blocked );

signals:
void styleChanged( QgsMapLayer* layer );

Expand All @@ -81,9 +88,10 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
void autoApply();
void undo();
void redo();
void updateCurrentWidgetLayer();

private slots:
void updateCurrentWidgetLayer();

void layerAboutToBeRemoved( QgsMapLayer* layer );
void liveApplyToggled( bool value );

Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsmaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ void QgsMapLayer::setBlendMode( QPainter::CompositionMode blendMode )
{
mBlendMode = blendMode;
emit blendModeChanged( blendMode );
emit styleChanged();
}

/** Read blend mode for layer */
Expand Down Expand Up @@ -1707,6 +1708,11 @@ QString QgsMapLayer::metadata()
return QString();
}

void QgsMapLayer::emitStyleChanged()
{
emit styleChanged();
}

void QgsMapLayer::setExtent( const QgsRectangle &r )
{
mExtent = r;
Expand Down
17 changes: 16 additions & 1 deletion src/core/qgsmaplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const { return QDateTime() ; }

/** Triggers an emission of the styleChanged() signal.
* @note added in QGIS 2.16
*/
void emitStyleChanged();

signals:

//! @deprecated in 2.4 - not emitted anymore
Expand Down Expand Up @@ -669,9 +674,19 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** Signal emitted when the blend mode is changed, through QgsMapLayer::setBlendMode() */
void blendModeChanged( QPainter::CompositionMode blendMode );

/** Signal emitted when renderer is changed */
/** Signal emitted when renderer is changed.
* @see styleChanged()
*/
void rendererChanged();

/** Signal emitted whenever a change affects the layer's style. Ie this may be triggered
* by renderer changes, label style changes, or other style changes such as blend
* mode or layer opacity changes.
* @note added in QGIS 2.16
* @see rendererChanged()
*/
void styleChanged();

/**
* Signal emitted when legend of the layer has changed
* @note added in 2.6
Expand Down
3 changes: 1 addition & 2 deletions src/core/qgspallabeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,10 +1244,9 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
layer->setCustomProperty( "labeling/zIndex", zIndex );

writeDataDefinedPropertyMap( layer, nullptr, dataDefinedProperties );
layer->emitStyleChanged();
}



void QgsPalLayerSettings::readXml( QDomElement& elem )
{
enabled = true;
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ void QgsVectorLayer::setDiagramRenderer( QgsDiagramRendererV2* r )
delete mDiagramRenderer;
mDiagramRenderer = r;
emit rendererChanged();
emit styleChanged();
}

QGis::GeometryType QgsVectorLayer::geometryType() const
Expand Down Expand Up @@ -2964,6 +2965,7 @@ void QgsVectorLayer::setRendererV2( QgsFeatureRendererV2 *r )
mSymbolFeatureCountMap.clear();

emit rendererChanged();
emit styleChanged();
}
}

Expand Down Expand Up @@ -3469,6 +3471,7 @@ void QgsVectorLayer::setFeatureBlendMode( QPainter::CompositionMode featureBlend
{
mFeatureBlendMode = featureBlendMode;
emit featureBlendModeChanged( featureBlendMode );
emit styleChanged();
}

/** Read blend mode for layer */
Expand All @@ -3482,6 +3485,7 @@ void QgsVectorLayer::setLayerTransparency( int layerTransparency )
{
mLayerTransparency = layerTransparency;
emit layerTransparencyChanged( layerTransparency );
emit styleChanged();
}

/** Read transparency for layer */
Expand Down
2 changes: 2 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnh
qDeleteAll( myEnhancements );

emit repaintRequested();
emit styleChanged();
}

void QgsRasterLayer::setDefaultContrastEnhancement()
Expand Down Expand Up @@ -1076,6 +1077,7 @@ void QgsRasterLayer::setRenderer( QgsRasterRenderer* theRenderer )
if ( !theRenderer ) { return; }
mPipe.set( theRenderer );
emit rendererChanged();
emit styleChanged();
}

void QgsRasterLayer::showProgress( int theValue )
Expand Down

2 comments on commit c3c5c43

@nirvn
Copy link
Contributor

@nirvn nirvn commented on c3c5c43 Jun 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nyalldawson , I'm not sure if it's this commit (going to figure this out in a minute), but editing a categorized, graduated symbol now crashes QGIS when pressing the [ < ] button. The trace is:

`
#0 QMetaObject::activate (sender=0x0, m=, local_signal_index=0, argv=0x7fffffffc310) at kernel/qobject.cpp:3472
#1 0x00007ffff6f2a854 in QgsPanelWidget::panelAccepted (this=0x0, _t1=0x0) at /home/webmaster/dev/cpp/QGIS/bm/src/gui/moc_qgspanelwidget.cxx:110
#2 0x00007ffff6eadc73 in QgsPanelWidget::acceptPanel (this=0x0) at /home/webmaster/dev/cpp/QGIS/src/gui/qgspanelwidget.cpp:76
#3 0x00007ffff6eae013 in QgsPanelWidgetStack::acceptCurrentPanel (this=0x14b6500) at /home/webmaster/dev/cpp/QGIS/src/gui/qgspanelwidget.cpp:145
#4 0x00007ffff6f2aa71 in QgsPanelWidgetStack::qt_static_metacall (_o=0x14b6500, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffffffc460)

at /home/webmaster/dev/cpp/QGIS/bm/src/gui/moc_qgspanelwidget.cxx:219

#5 0x00007ffff58f6010 in QMetaObject::activate (sender=sender@entry=0x14b63c0, m=m@entry=0x7ffff5741f60 QAbstractButton::staticMetaObject,

local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x0) at kernel/qobject.cpp:3567

#6 0x00007ffff52cccb0 in QAbstractButton::pressed (this=this@entry=0x14b63c0) at .moc/release-shared/moc_qabstractbutton.cpp:206
#7 0x00007ffff5002366 in QAbstractButtonPrivate::emitPressed (this=this@entry=0x17aba60) at widgets/qabstractbutton.cpp:562
#8 0x00007ffff5002cd3 in QAbstractButton::mousePressEvent (this=0x14b63c0, e=0x7fffffffca20) at widgets/qabstractbutton.cpp:1098
#9 0x00007ffff4c7f490 in QWidget::event (this=0x14b63c0, event=0x7fffffffca20) at kernel/qwidget.cpp:8385
#10 0x00007ffff4c27fdc in QApplicationPrivate::notify_helper (this=this@entry=0x947f00, receiver=receiver@entry=0x14b63c0, e=e@entry=0x7fffffffca20)

at kernel/qapplication.cpp:4570

#11 0x00007ffff4c2f0d6 in QApplication::notify (this=, receiver=0x14b63c0, e=0x7fffffffca20) at kernel/qapplication.cpp:4113
#12 0x00007ffff5fc5999 in QgsApplication::notify (this=0x7fffffffdae0, receiver=0x14b63c0, event=0x7fffffffca20)

at /home/webmaster/dev/cpp/QGIS/src/core/qgsapplication.cpp:281

#13 0x00007ffff58e190d in QCoreApplication::notifyInternal (this=0x7fffffffdae0, receiver=receiver@entry=0x14b63c0, event=event@entry=0x7fffffffca20)

at kernel/qcoreapplication.cpp:955

#14 0x00007ffff4c2e6dd in QCoreApplication::sendEvent (event=, receiver=)

at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:231

#15 QApplicationPrivate::sendMouseEvent (receiver=receiver@entry=0x14b63c0, event=event@entry=0x7fffffffca20, alienWidget=alienWidget@entry=0x14b63c0,

nativeWidget=nativeWidget@entry=0xce80b0, buttonDown=buttonDown@entry=0x7ffff5753368 <qt_button_down>, lastMouseReceiver=..., spontaneous=true)
at kernel/qapplication.cpp:3178

#16 0x00007ffff4cac3f2 in QETWidget::translateMouseEvent (this=this@entry=0xce80b0, event=event@entry=0x7fffffffcd80) at kernel/qapplication_x11.cpp:4638
#17 0x00007ffff4cabc83 in QApplication::x11ProcessEvent (this=0x7fffffffdae0, event=event@entry=0x7fffffffcd80) at kernel/qapplication_x11.cpp:3626
#18 0x00007ffff4cd5542 in x11EventSourceDispatch (s=0x947960, callback=0x0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
#19 0x00007fffed33d1a7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#20 0x00007fffed33d400 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#21 0x00007fffed33d4ac in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#22 0x00007ffff59122ae in QEventDispatcherGlib::processEvents (this=0x8a4d80, flags=...) at kernel/qeventdispatcher_glib.cpp:450
#23 0x00007ffff4cd5616 in QGuiEventDispatcherGlib::processEvents (this=, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#24 0x00007ffff58e018f in QEventLoop::processEvents (this=this@entry=0x7fffffffd160, flags=...) at kernel/qeventloop.cpp:149
#25 0x00007ffff58e04f5 in QEventLoop::exec (this=this@entry=0x7fffffffd160, flags=...) at kernel/qeventloop.cpp:204
#26 0x00007ffff58e64b9 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1227
#27 0x0000000000409ccd in main (argc=1, argv=0x7fffffffddc8) at /home/webmaster/dev/cpp/QGIS/src/app/main.cpp:1257

`

@nirvn
Copy link
Contributor

@nirvn nirvn commented on c3c5c43 Jun 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, just confirmed, the build start crashing when including this commit c3c5c43 (Avoid style dock flashing when editing layers).

Steps to reproduce the crash:

  • Load a vector layer, open the style dock
  • Set renderer to categorized, pick a field and classify
  • Edit on one category to edit its symbol
  • Click on the [ < ] back arrow, by which stage you'll see an empty style dock panel
  • Click on the [ < ] back arrow again, boom

Please sign in to comment.