1 /***************************************************************************
2     qgscolorrampbutton.cpp - Color ramp button
3      --------------------------------------
4     Date                 : November 27, 2016
5     Copyright            : (C) 2016 by Mathieu Pellerin
6     Email                : nirvn dot asia at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #include "qgscolorrampbutton.h"
17 #include "qgscolorramp.h"
18 #include "qgsapplication.h"
19 #include "qgslogger.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgsstyle.h"
22 
23 #include "qgsstylesavedialog.h"
24 #include "qgsgradientcolorrampdialog.h"
25 #include "qgslimitedrandomcolorrampdialog.h"
26 #include "qgscolorbrewercolorrampdialog.h"
27 #include "qgscptcitycolorrampdialog.h"
28 #include "qgspresetcolorrampdialog.h"
29 
30 #include <QAction>
31 #include <QInputDialog>
32 #include <QMessageBox>
33 #include <QMouseEvent>
34 #include <QMenu>
35 #include <QPainter>
36 #include <QPushButton>
37 
QgsColorRampButton(QWidget * parent,const QString & dialogTitle)38 QgsColorRampButton::QgsColorRampButton( QWidget *parent, const QString &dialogTitle )
39   : QToolButton( parent )
40   , mColorRampDialogTitle( dialogTitle.isEmpty() ? tr( "Select Color Ramp" ) : dialogTitle )
41 {
42   setAcceptDrops( true );
43   setMinimumSize( QSize( 24, 16 ) );
44   connect( this, &QPushButton::clicked, this, &QgsColorRampButton::buttonClicked );
45 
46   //setup drop-down menu
47   mMenu = new QMenu( this );
48   connect( mMenu, &QMenu::aboutToShow, this, &QgsColorRampButton::prepareMenu );
49   setMenu( mMenu );
50 
51   mAllRampsMenu = new QMenu( mMenu );
52   mAllRampsMenu->setTitle( tr( "All Color Ramps" ) );
53 
54   setPopupMode( QToolButton::MenuButtonPopup );
55 
56   mStyle = QgsStyle::defaultStyle();
57 }
58 
59 QgsColorRampButton::~QgsColorRampButton() = default;
60 
sizeHint() const61 QSize QgsColorRampButton::sizeHint() const
62 {
63   //make sure height of button looks good under different platforms
64 #ifdef Q_OS_WIN
65   return QSize( 120, static_cast<int>( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height( ), 22.0 ) ) );
66 #else
67   // Adjust height for HiDPI screens
68   return QSize( 120, static_cast<int>( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height( ) * 1.4, 28.0 ) ) );
69 #endif
70 }
71 
showColorRampDialog()72 void QgsColorRampButton::showColorRampDialog()
73 {
74   QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
75   const bool panelMode = panel && panel->dockMode();
76 
77   std::unique_ptr< QgsColorRamp > currentRamp( colorRamp() );
78   if ( !currentRamp )
79     return;
80 
81   setColorRampName( QString() );
82 
83   if ( currentRamp->type() == QgsGradientColorRamp::typeString() )
84   {
85     QgsGradientColorRamp *gradRamp = static_cast<QgsGradientColorRamp *>( currentRamp.get() );
86     QgsGradientColorRampDialog dlg( *gradRamp, this );
87     dlg.setWindowTitle( mColorRampDialogTitle );
88     if ( dlg.exec() )
89     {
90       setColorRamp( dlg.ramp().clone() );
91     }
92   }
93   else if ( currentRamp->type() == QgsLimitedRandomColorRamp::typeString() )
94   {
95     QgsLimitedRandomColorRamp *randRamp = static_cast<QgsLimitedRandomColorRamp *>( currentRamp.get() );
96     if ( panelMode )
97     {
98       QgsLimitedRandomColorRampWidget *widget = new QgsLimitedRandomColorRampWidget( *randRamp, this );
99       widget->setPanelTitle( tr( "Edit Ramp" ) );
100       connect( widget, &QgsLimitedRandomColorRampWidget::changed, this, &QgsColorRampButton::rampWidgetUpdated );
101       panel->openPanel( widget );
102     }
103     else
104     {
105       QgsLimitedRandomColorRampDialog dlg( *randRamp, this );
106       if ( dlg.exec() )
107       {
108         setColorRamp( dlg.ramp().clone() );
109       }
110     }
111   }
112   else if ( currentRamp->type() == QgsPresetSchemeColorRamp::typeString() )
113   {
114     QgsPresetSchemeColorRamp *presetRamp = static_cast<QgsPresetSchemeColorRamp *>( currentRamp.get() );
115     if ( panelMode )
116     {
117       QgsPresetColorRampWidget *widget = new QgsPresetColorRampWidget( *presetRamp, this );
118       widget->setPanelTitle( tr( "Edit Ramp" ) );
119       connect( widget, &QgsPresetColorRampWidget::changed, this, &QgsColorRampButton::rampWidgetUpdated );
120       panel->openPanel( widget );
121     }
122     else
123     {
124       QgsPresetColorRampDialog dlg( *presetRamp, this );
125       if ( dlg.exec() )
126       {
127         setColorRamp( dlg.ramp().clone() );
128       }
129     }
130   }
131   else if ( currentRamp->type() == QgsColorBrewerColorRamp::typeString() )
132   {
133     QgsColorBrewerColorRamp *brewerRamp = static_cast<QgsColorBrewerColorRamp *>( currentRamp.get() );
134     if ( panelMode )
135     {
136       QgsColorBrewerColorRampWidget *widget = new QgsColorBrewerColorRampWidget( *brewerRamp, this );
137       widget->setPanelTitle( tr( "Edit Ramp" ) );
138       connect( widget, &QgsColorBrewerColorRampWidget::changed, this, &QgsColorRampButton::rampWidgetUpdated );
139       panel->openPanel( widget );
140     }
141     else
142     {
143       QgsColorBrewerColorRampDialog dlg( *brewerRamp, this );
144       if ( dlg.exec() )
145       {
146         setColorRamp( dlg.ramp().clone() );
147       }
148     }
149   }
150   else if ( currentRamp->type() == QgsCptCityColorRamp::typeString() )
151   {
152     QgsCptCityColorRamp *cptCityRamp = static_cast<QgsCptCityColorRamp *>( currentRamp.get() );
153     QgsCptCityColorRampDialog dlg( *cptCityRamp, this );
154     if ( dlg.exec() )
155     {
156       if ( dlg.saveAsGradientRamp() )
157       {
158         setColorRamp( dlg.ramp().cloneGradientRamp() );
159       }
160       else
161       {
162         setColorRamp( dlg.ramp().clone() );
163       }
164     }
165   }
166 }
167 
setToDefaultColorRamp()168 void QgsColorRampButton::setToDefaultColorRamp()
169 {
170   if ( !mDefaultColorRamp )
171   {
172     return;
173   }
174 
175   setColorRamp( mDefaultColorRamp.get() );
176 }
177 
setToNull()178 void QgsColorRampButton::setToNull()
179 {
180   setColorRamp( nullptr );
181 }
182 
event(QEvent * e)183 bool QgsColorRampButton::event( QEvent *e )
184 {
185   if ( e->type() == QEvent::ToolTip )
186   {
187     if ( !colorRampName().isEmpty() )
188     {
189       setToolTip( colorRampName() );
190     }
191   }
192   return QToolButton::event( e );
193 }
194 
mousePressEvent(QMouseEvent * e)195 void QgsColorRampButton::mousePressEvent( QMouseEvent *e )
196 {
197   if ( e->button() == Qt::RightButton )
198   {
199     QToolButton::showMenu();
200     return;
201   }
202   QToolButton::mousePressEvent( e );
203 }
204 
createMenuIcon(QgsColorRamp * colorramp)205 QPixmap QgsColorRampButton::createMenuIcon( QgsColorRamp *colorramp )
206 {
207   //create an icon pixmap
208   const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
209   const QPixmap pixmap = QgsSymbolLayerUtils::colorRampPreviewPixmap( colorramp, QSize( iconSize, iconSize ) );
210   return pixmap;
211 }
212 
buttonClicked()213 void QgsColorRampButton::buttonClicked()
214 {
215   if ( !isRandomColorRamp() && !isNull() )
216   {
217     showColorRampDialog();
218   }
219   else
220   {
221     QToolButton::showMenu();
222   }
223 }
224 
prepareMenu()225 void QgsColorRampButton::prepareMenu()
226 {
227   mMenu->clear();
228 
229   QAction *invertAction = new QAction( tr( "Invert Color Ramp" ), this );
230   invertAction->setEnabled( !isNull() && !isRandomColorRamp() );
231   mMenu->addAction( invertAction );
232   connect( invertAction, &QAction::triggered, this, &QgsColorRampButton::invertColorRamp );
233 
234   if ( mShowNull )
235   {
236     QAction *nullAction = new QAction( tr( "Clear Current Ramp" ), this );
237     mMenu->addAction( nullAction );
238     connect( nullAction, &QAction::triggered, this, &QgsColorRampButton::setToNull );
239   }
240 
241   mMenu->addSeparator();
242 
243   //show default color option if set
244   if ( mDefaultColorRamp )
245   {
246     QAction *defaultColorRampAction = new QAction( tr( "Default Color Ramp" ), this );
247     defaultColorRampAction->setIcon( createMenuIcon( mDefaultColorRamp.get() ) );
248     mMenu->addAction( defaultColorRampAction );
249     connect( defaultColorRampAction, &QAction::triggered, this, &QgsColorRampButton::setToDefaultColorRamp );
250   }
251 
252   if ( mShowRandomColorRamp )
253   {
254     QAction *randomColorRampAction = new QAction( tr( "Random Color Ramp" ), this );
255     randomColorRampAction->setCheckable( true );
256     randomColorRampAction->setChecked( isRandomColorRamp() );
257     mMenu->addAction( randomColorRampAction );
258     connect( randomColorRampAction, &QAction::triggered, this, &QgsColorRampButton::setRandomColorRamp );
259 
260     if ( isRandomColorRamp() || dynamic_cast<QgsLimitedRandomColorRamp *>( mColorRamp.get() ) )
261     {
262       QAction *shuffleRandomColorRampAction = new QAction( tr( "Shuffle Random Colors" ), this );
263       mMenu->addAction( shuffleRandomColorRampAction );
264       connect( shuffleRandomColorRampAction, &QAction::triggered, this, &QgsColorRampButton::colorRampChanged );
265     }
266   }
267 
268   mMenu->addSeparator();
269 
270   QStringList rampNames = mStyle->symbolsOfFavorite( QgsStyle::ColorrampEntity );
271   rampNames.sort();
272   const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
273   for ( QStringList::iterator it = rampNames.begin(); it != rampNames.end(); ++it )
274   {
275     std::unique_ptr< QgsColorRamp > ramp( mStyle->colorRamp( *it ) );
276 
277     if ( !mShowGradientOnly || ( ramp->type() == QgsGradientColorRamp::typeString() || ramp->type() == QgsCptCityColorRamp::typeString() ) )
278     {
279       const QIcon icon = QgsSymbolLayerUtils::colorRampPreviewIcon( ramp.get(), QSize( iconSize, iconSize ) );
280       QAction *ra = new QAction( *it, this );
281       ra->setIcon( icon );
282       connect( ra, &QAction::triggered, this, &QgsColorRampButton::loadColorRamp );
283       mMenu->addAction( ra );
284     }
285   }
286 
287   mMenu->addSeparator();
288 
289   mAllRampsMenu->clear();
290   mMenu->addMenu( mAllRampsMenu );
291   rampNames = mStyle->colorRampNames();
292   rampNames.sort();
293   for ( QStringList::iterator it = rampNames.begin(); it != rampNames.end(); ++it )
294   {
295     std::unique_ptr< QgsColorRamp > ramp( mStyle->colorRamp( *it ) );
296 
297     if ( !mShowGradientOnly || ( ramp->type() == QgsGradientColorRamp::typeString() || ramp->type() == QgsCptCityColorRamp::typeString() ) )
298     {
299       const QIcon icon = QgsSymbolLayerUtils::colorRampPreviewIcon( ramp.get(), QSize( iconSize, iconSize ) );
300       QAction *ra = new QAction( *it, this );
301       ra->setIcon( icon );
302       connect( ra, &QAction::triggered, this, &QgsColorRampButton::loadColorRamp );
303       mAllRampsMenu->addAction( ra );
304     }
305   }
306 
307   mMenu->addSeparator();
308 
309   QAction *newColorRampAction = new QAction( tr( "Create New Color Ramp…" ), this );
310   connect( newColorRampAction, &QAction::triggered, this, &QgsColorRampButton::createColorRamp );
311   mMenu->addAction( newColorRampAction );
312 
313   QAction *editColorRampAction = new QAction( tr( "Edit Color Ramp…" ), this );
314   editColorRampAction->setEnabled( !isNull() && !isRandomColorRamp() );
315   connect( editColorRampAction, &QAction::triggered, this, &QgsColorRampButton::showColorRampDialog );
316   mMenu->addAction( editColorRampAction );
317 
318   QAction *saveColorRampAction = new QAction( tr( "Save Color Ramp…" ), this );
319   saveColorRampAction->setEnabled( !isNull() && !isRandomColorRamp() );
320   connect( saveColorRampAction, &QAction::triggered, this, &QgsColorRampButton::saveColorRamp );
321   mMenu->addAction( saveColorRampAction );
322 }
323 
loadColorRamp()324 void QgsColorRampButton::loadColorRamp()
325 {
326   QAction *selectedItem = qobject_cast<QAction *>( sender() );
327   if ( selectedItem )
328   {
329     const QString name = selectedItem->iconText();
330     setColorRampName( name );
331     setColorRampFromName( name );
332   }
333 }
334 
createColorRamp()335 void QgsColorRampButton::createColorRamp()
336 {
337 
338   bool ok = true;
339 
340   QList< QPair< QString, QString > > rampTypes = QgsColorRamp::rampTypes();
341   QStringList rampTypeNames;
342   rampTypeNames.reserve( rampTypes.size() );
343   if ( mShowGradientOnly )
344   {
345     rampTypes.erase( std::remove_if( rampTypes.begin(), rampTypes.end(), []( const QPair< QString, QString > &type )
346     {
347       return type.first != QgsGradientColorRamp::typeString() && type.first != QgsCptCityColorRamp::typeString();
348     } ), rampTypes.end() );
349   }
350 
351   for ( const QPair< QString, QString > &type : rampTypes )
352     rampTypeNames << type.second;
353 
354   const QString selectedRampTypeName = QInputDialog::getItem( this, tr( "Color ramp type" ),
355                                        tr( "Please select color ramp type:" ), rampTypeNames, 0, false, &ok );
356 
357   if ( !ok || selectedRampTypeName.isEmpty() )
358     return;
359 
360   const QString rampType = rampTypes.value( rampTypeNames.indexOf( selectedRampTypeName ) ).first;
361 
362   QgsColorRamp *ramp = nullptr;
363   if ( rampType == QgsGradientColorRamp::typeString() )
364   {
365     ramp = new QgsGradientColorRamp();
366   }
367   else if ( rampType == QgsLimitedRandomColorRamp::typeString() )
368   {
369     ramp = new QgsLimitedRandomColorRamp();
370   }
371   else if ( rampType == QgsColorBrewerColorRamp::typeString() )
372   {
373     ramp = new QgsColorBrewerColorRamp();
374   }
375   else if ( rampType == QgsPresetSchemeColorRamp::typeString() )
376   {
377     ramp = new QgsPresetSchemeColorRamp();
378   }
379   else if ( rampType == QgsCptCityColorRamp::typeString() )
380   {
381     ramp = new QgsCptCityColorRamp( QString(), QString() );
382   }
383   else
384   {
385     QgsDebugMsg( "invalid ramp type " + rampType );
386     return;
387   }
388 
389   setColorRamp( ramp );
390   delete ramp;
391 
392   showColorRampDialog();
393 }
394 
saveColorRamp()395 void QgsColorRampButton::saveColorRamp()
396 {
397   QgsStyleSaveDialog saveDlg( this, QgsStyle::ColorrampEntity );
398   if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
399   {
400     return;
401   }
402 
403   // check if there is no symbol with same name
404   if ( mStyle->symbolNames().contains( saveDlg.name() ) )
405   {
406     const int res = QMessageBox::warning( this, tr( "Save Color Ramp" ),
407                                           tr( "Color ramp with name '%1' already exists. Overwrite?" )
408                                           .arg( saveDlg.name() ),
409                                           QMessageBox::Yes | QMessageBox::No );
410     if ( res != QMessageBox::Yes )
411     {
412       return;
413     }
414     mStyle->removeColorRamp( saveDlg.name() );
415   }
416 
417   const QStringList colorRampTags = saveDlg.tags().split( ',' );
418 
419   // add new symbol to style and re-populate the list
420   QgsColorRamp *ramp = colorRamp();
421   mStyle->addColorRamp( saveDlg.name(), ramp );
422   mStyle->saveColorRamp( saveDlg.name(), ramp, saveDlg.isFavorite(), colorRampTags );
423 
424   setColorRampName( saveDlg.name() );
425 }
426 
invertColorRamp()427 void QgsColorRampButton::invertColorRamp()
428 {
429   mColorRamp->invert();
430   setButtonBackground();
431   emit colorRampChanged();
432 }
433 
changeEvent(QEvent * e)434 void QgsColorRampButton::changeEvent( QEvent *e )
435 {
436   if ( e->type() == QEvent::EnabledChange )
437   {
438     setButtonBackground();
439   }
440   QToolButton::changeEvent( e );
441 }
442 
443 #if 0 // causes too many cyclical updates, but may be needed on some platforms
444 void QgsColorRampButton::paintEvent( QPaintEvent *e )
445 {
446   QToolButton::paintEvent( e );
447 
448   if ( !mBackgroundSet )
449   {
450     setButtonBackground();
451   }
452 }
453 #endif
454 
showEvent(QShowEvent * e)455 void QgsColorRampButton::showEvent( QShowEvent *e )
456 {
457   setButtonBackground();
458   QToolButton::showEvent( e );
459 }
460 
resizeEvent(QResizeEvent * event)461 void QgsColorRampButton::resizeEvent( QResizeEvent *event )
462 {
463   QToolButton::resizeEvent( event );
464   //recalculate icon size and redraw icon
465   mIconSize = QSize();
466   setButtonBackground( mColorRamp.get() );
467 }
468 
setColorRamp(QgsColorRamp * colorramp)469 void QgsColorRampButton::setColorRamp( QgsColorRamp *colorramp )
470 {
471   if ( colorramp == mColorRamp.get() )
472     return;
473 
474   mColorRamp.reset( colorramp ? colorramp->clone() : nullptr );
475 
476   setButtonBackground();
477   if ( isEnabled() )
478   {
479     emit colorRampChanged();
480   }
481 }
482 
setColorRampFromName(const QString & name)483 void QgsColorRampButton::setColorRampFromName( const QString &name )
484 {
485   if ( !name.isEmpty() )
486   {
487     const std::unique_ptr< QgsColorRamp > ramp( mStyle->colorRamp( name ) );
488     if ( ramp )
489     {
490       setColorRamp( ramp.get() );
491     }
492   }
493 }
494 
setRandomColorRamp()495 void QgsColorRampButton::setRandomColorRamp()
496 {
497   if ( !isRandomColorRamp() )
498   {
499     const std::unique_ptr< QgsRandomColorRamp > newRamp( new QgsRandomColorRamp() );
500     setColorRamp( newRamp.get() );
501   }
502 }
503 
setButtonBackground(QgsColorRamp * colorramp)504 void QgsColorRampButton::setButtonBackground( QgsColorRamp *colorramp )
505 {
506   QgsColorRamp *backgroundColorRamp = colorramp;
507   if ( !colorramp )
508   {
509     backgroundColorRamp = mColorRamp.get();
510   }
511 
512   QSize currentIconSize;
513   //icon size is button size with a small margin
514   if ( menu() )
515   {
516     if ( !mIconSize.isValid() )
517     {
518       //calculate size of push button part of widget (ie, without the menu drop-down button part)
519       QStyleOptionToolButton opt;
520       initStyleOption( &opt );
521       const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
522                                this );
523       //make sure height of icon looks good under different platforms
524 #ifdef Q_OS_WIN
525       mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
526 #else
527       mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
528 #endif
529     }
530     currentIconSize = mIconSize;
531   }
532   else
533   {
534     //no menu
535 #ifdef Q_OS_WIN
536     currentIconSize = QSize( width() - 10, height() - 6 );
537 #else
538     currentIconSize = QSize( width() - 10, height() - 12 );
539 #endif
540   }
541 
542   if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
543   {
544     return;
545   }
546 
547   QPixmap pm;
548   if ( isRandomColorRamp() )
549   {
550     //create a "random colors" label
551     pm = QPixmap( currentIconSize );
552     pm.fill( Qt::transparent );
553 
554     QPainter painter;
555     const QPen pen  = ( palette().buttonText().color() );
556 
557     painter.begin( &pm );
558     painter.setPen( pen );
559     painter.drawText( QRect( 0, 0, currentIconSize.width(), currentIconSize.height() ), Qt::AlignCenter, QStringLiteral( "Random colors" ) );
560     painter.end();
561   }
562   else
563   {
564     //create an icon pixmap
565     if ( backgroundColorRamp )
566     {
567       pm = QgsSymbolLayerUtils::colorRampPreviewPixmap( backgroundColorRamp, currentIconSize );
568     }
569   }
570 
571   setIconSize( currentIconSize );
572   setIcon( pm );
573 }
574 
colorRamp() const575 QgsColorRamp *QgsColorRampButton::colorRamp() const
576 {
577   return mColorRamp ? mColorRamp->clone() : nullptr;
578 }
579 
setColorRampDialogTitle(const QString & title)580 void QgsColorRampButton::setColorRampDialogTitle( const QString &title )
581 {
582   mColorRampDialogTitle = title;
583 }
584 
colorRampDialogTitle() const585 QString QgsColorRampButton::colorRampDialogTitle() const
586 {
587   return mColorRampDialogTitle;
588 }
589 
setShowMenu(const bool showMenu)590 void QgsColorRampButton::setShowMenu( const bool showMenu )
591 {
592   setMenu( showMenu ? mMenu : nullptr );
593   setPopupMode( showMenu ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup );
594   //force recalculation of icon size
595   mIconSize = QSize();
596   setButtonBackground( mColorRamp.get() );
597 }
598 
showMenu() const599 bool QgsColorRampButton::showMenu() const
600 {
601   return menu() ? true : false;
602 }
603 
setDefaultColorRamp(QgsColorRamp * colorramp)604 void QgsColorRampButton::setDefaultColorRamp( QgsColorRamp *colorramp )
605 {
606   mDefaultColorRamp.reset( colorramp ? colorramp->clone() : nullptr );
607 }
608 
defaultColorRamp() const609 QgsColorRamp *QgsColorRampButton::defaultColorRamp() const
610 {
611   return mDefaultColorRamp ? mDefaultColorRamp->clone() : nullptr;
612 }
613 
isRandomColorRamp() const614 bool QgsColorRampButton::isRandomColorRamp() const
615 {
616   return dynamic_cast<QgsRandomColorRamp *>( mColorRamp.get() );
617 }
618 
setShowNull(bool showNull)619 void QgsColorRampButton::setShowNull( bool showNull )
620 {
621   mShowNull = showNull;
622 }
623 
showNull() const624 bool QgsColorRampButton::showNull() const
625 {
626   return mShowNull;
627 }
628 
isNull() const629 bool QgsColorRampButton::isNull() const
630 {
631   return !mColorRamp;
632 }
633 
rampWidgetUpdated()634 void QgsColorRampButton::rampWidgetUpdated()
635 {
636   QgsLimitedRandomColorRampWidget *limitedRampWidget = qobject_cast< QgsLimitedRandomColorRampWidget * >( sender() );
637   if ( limitedRampWidget )
638   {
639     setColorRamp( limitedRampWidget->ramp().clone() );
640     emit colorRampChanged();
641     return;
642   }
643   QgsColorBrewerColorRampWidget *colorBrewerRampWidget = qobject_cast< QgsColorBrewerColorRampWidget * >( sender() );
644   if ( colorBrewerRampWidget )
645   {
646     setColorRamp( colorBrewerRampWidget->ramp().clone() );
647     emit colorRampChanged();
648     return;
649   }
650   QgsPresetColorRampWidget *presetRampWidget = qobject_cast< QgsPresetColorRampWidget * >( sender() );
651   if ( presetRampWidget )
652   {
653     setColorRamp( presetRampWidget->ramp().clone() );
654     emit colorRampChanged();
655     return;
656   }
657 }
658