QGIS API Documentation  2.8.6-Wien
qgsvectorgradientcolorrampv2dialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorgradientcolorrampv2dialog.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk 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 
17 
18 #include "qgsvectorcolorrampv2.h"
19 #include "qgsdialog.h"
20 #include "qgscolordialog.h"
21 #include "qgscptcityarchive.h"
22 #include "qgscolordialog.h"
23 
24 #include <QColorDialog>
25 #include <QInputDialog>
26 #include <QPainter>
27 #include <QSettings>
28 #include <QTableWidget>
29 #include <QTextEdit>
30 
32  : QDialog( parent ), mRamp( ramp ), mCurrentItem( 0 )
33 {
34  setupUi( this );
35 #ifdef Q_OS_MAC
36  setWindowModality( Qt::WindowModal );
37 #endif
38 
39  btnColor1->setAllowAlpha( true );
40  btnColor1->setColorDialogTitle( tr( "Select ramp color" ) );
41  btnColor1->setContext( "symbology" );
42  btnColor1->setShowNoColor( true );
43  btnColor1->setNoColorString( tr( "Transparent" ) );
44  btnColor2->setAllowAlpha( true );
45  btnColor2->setColorDialogTitle( tr( "Select ramp color" ) );
46  btnColor2->setContext( "symbology" );
47  btnColor2->setShowNoColor( true );
48  btnColor2->setNoColorString( tr( "Transparent" ) );
49  connect( btnColor1, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setColor1( const QColor& ) ) );
50  connect( btnColor2, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setColor2( const QColor& ) ) );
51 
52  // handle stops
53  updateStops();
54  connect( groupStops, SIGNAL( toggled( bool ) ), this, SLOT( toggledStops( bool ) ) );
55  connect( btnAddStop, SIGNAL( clicked() ), this, SLOT( addStop() ) );
56  connect( btnRemoveStop, SIGNAL( clicked() ), this, SLOT( removeStop() ) );
57  connect( treeStops, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( stopDoubleClicked( QTreeWidgetItem*, int ) ) );
58 
59  // fill type combobox
60  cboType->blockSignals( true );
61  cboType->addItem( tr( "Discrete" ) );
62  cboType->addItem( tr( "Continuous" ) );
63  if ( mRamp->isDiscrete() )
64  cboType->setCurrentIndex( 0 );
65  else
66  cboType->setCurrentIndex( 1 );
67  cboType->blockSignals( false );
68 
69  // information button if needed
70  // QPushButton* button = buttonBox->addButton( tr( "Information" ), QDialogButtonBox::ActionRole );
71  if ( mRamp->info().isEmpty() )
72  btnInformation->setEnabled( false );
73  // else
74  // connect( button, SIGNAL( pressed() ), this, SLOT( showInformation() ) );
75 
76  updatePreview();
77 }
78 
80 {
81  if (( index == 0 && mRamp->isDiscrete() ) ||
82  ( index == 1 && !mRamp->isDiscrete() ) )
83  return;
84  mRamp->convertToDiscrete( index == 0 );
85  updateStops();
86  updatePreview();
87 }
88 
90 {
91  if ( mRamp->info().isEmpty() )
92  return;
93 
94  QgsDialog *dlg = new QgsDialog( this );
95  QLabel *label = 0;
96 
97  // information table
98  QTableWidget *tableInfo = new QTableWidget( dlg );
99  tableInfo->verticalHeader()->hide();
100  tableInfo->horizontalHeader()->hide();
101  tableInfo->setRowCount( mRamp->info().count() );
102  tableInfo->setColumnCount( 2 );
103  int i = 0;
104  QgsStringMap rampInfo = mRamp->info();
105  for ( QgsStringMap::const_iterator it = rampInfo.constBegin();
106  it != rampInfo.constEnd(); ++it )
107  {
108  if ( it.key().startsWith( "cpt-city" ) )
109  continue;
110  tableInfo->setItem( i, 0, new QTableWidgetItem( it.key() ) );
111  tableInfo->setItem( i, 1, new QTableWidgetItem( it.value() ) );
112  tableInfo->resizeRowToContents( i );
113  i++;
114  }
115  tableInfo->resizeColumnToContents( 0 );
116  tableInfo->horizontalHeader()->setStretchLastSection( true );
117  tableInfo->setRowCount( i );
118  tableInfo->setFixedHeight( tableInfo->rowHeight( 0 ) * i + 5 );
119  dlg->layout()->addWidget( tableInfo );
120  dlg->resize( 600, 250 );
121 
122  dlg->layout()->addSpacing( 5 );
123 
124  // gradient file
125  QString gradientFile = mRamp->info().value( "cpt-city-gradient" );
126  if ( ! gradientFile.isNull() )
127  {
128  QString fileName = gradientFile;
129  fileName.replace( "<cpt-city>", QgsCptCityArchive::defaultBaseDir() );
130  if ( ! QFile::exists( fileName ) )
131  {
132  fileName = gradientFile;
133  fileName.replace( "<cpt-city>", "http://soliton.vm.bytemark.co.uk/pub/cpt-city" );
134  }
135  label = new QLabel( tr( "Gradient file : %1" ).arg( fileName ), dlg );
136  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
137  dlg->layout()->addSpacing( 5 );
138  dlg->layout()->addWidget( label );
139  }
140 
141  // license file
142  QString licenseFile = mRamp->info().value( "cpt-city-license" );
143  if ( !licenseFile.isNull() )
144  {
145  QString fileName = licenseFile;
146  fileName.replace( "<cpt-city>", QgsCptCityArchive::defaultBaseDir() );
147  if ( ! QFile::exists( fileName ) )
148  {
149  fileName = licenseFile;
150  fileName.replace( "<cpt-city>", "http://soliton.vm.bytemark.co.uk/pub/cpt-city" );
151  }
152  label = new QLabel( tr( "License file : %1" ).arg( fileName ), dlg );
153  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
154  dlg->layout()->addSpacing( 5 );
155  dlg->layout()->addWidget( label );
156  if ( QFile::exists( fileName ) )
157  {
158  QTextEdit *textEdit = new QTextEdit( dlg );
159  textEdit->setReadOnly( true );
160  QFile file( fileName );
161  if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
162  {
163  textEdit->setText( file.readAll() );
164  file.close();
165  dlg->layout()->addSpacing( 5 );
166  dlg->layout()->addWidget( textEdit );
167  dlg->resize( 600, 500 );
168  }
169  }
170  }
171 
172  dlg->show(); //non modal
173 }
174 
176 {
177  QgsGradientStopsList stops = mRamp->stops();
178  groupStops->setChecked( !stops.isEmpty() );
179 
180  QList<QTreeWidgetItem *> items;
181  for ( QgsGradientStopsList::iterator it = stops.begin();
182  it != stops.end(); ++it )
183  {
184  double val = it->offset * 100.0;
185  QStringList lst;
186  lst << "." << QString(( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
187  QTreeWidgetItem* item = new QTreeWidgetItem( lst );
188 
189  setStopColor( item, it->color );
190  item->setData( 0, StopOffsetRole, it->offset );
191 
192  items.append( item );
193  }
194  treeStops->clear();
195  treeStops->insertTopLevelItems( 0, items );
196  treeStops->resizeColumnToContents( 0 );
197  treeStops->setColumnWidth( 0, treeStops->columnWidth( 0 ) + 20 );
198  treeStops->sortByColumn( 1, Qt::AscendingOrder );
199  treeStops->setSortingEnabled( true );
200 }
201 
203 {
204  // update ramp stops from the tree widget
205  QgsGradientStopsList stops;
206  if ( groupStops->isChecked() )
207  {
208  int count = treeStops->topLevelItemCount();
209  for ( int i = 0; i < count; i++ )
210  {
211  QTreeWidgetItem* item = treeStops->topLevelItem( i );
212  double offset = item->data( 0, StopOffsetRole ).toDouble();
213  QColor color = item->data( 0, StopColorRole ).value<QColor>();
214  stops.append( QgsGradientStop( offset, color ) );
215  }
216  }
217  mRamp->setStops( stops );
218 
219  // generate the preview
220  QSize size( 300, 40 );
221  lblPreview->setPixmap( QgsSymbolLayerV2Utils::colorRampPreviewPixmap( mRamp, size ) );
222 
223  btnColor1->blockSignals( true );
224  btnColor1->setColor( mRamp->color1() );
225  btnColor1->blockSignals( false );
226  btnColor2->blockSignals( true );
227  btnColor2->setColor( mRamp->color2() );
228  btnColor2->blockSignals( false );
229 }
230 
232 {
233  mRamp->setColor1( color );
234  updatePreview();
235 }
236 
238 {
239  mRamp->setColor2( color );
240  updatePreview();
241 }
242 
243 void QgsVectorGradientColorRampV2Dialog::setStopColor( QTreeWidgetItem* item, QColor color )
244 {
245  QSize iconSize( 16, 16 );
246  QPixmap pixmap( iconSize );
247  pixmap.fill( QColor( 0, 0, 0, 0 ) );
248  QRect rect( 1, 1, iconSize.width() - 2, iconSize.height() - 2 );
249 
250  // draw a slightly rounded rectangle
251  QPainter p;
252  p.begin( &pixmap );
253  p.setPen( Qt::NoPen );
254  p.setRenderHint( QPainter::Antialiasing );
255  p.setBrush( color );
256  p.drawRoundedRect( rect, 2, 2 );
257  p.end();
258 
259  item->setIcon( 0, QIcon( pixmap ) );
260  item->setData( 0, StopColorRole, color );
261  item->setText( 0, color.name() );
262 }
263 
265 {
266  if ( mCurrentItem )
267  {
268  setStopColor( mCurrentItem, newColor );
269  updatePreview();
270  }
271 }
272 
273 void QgsVectorGradientColorRampV2Dialog::stopDoubleClicked( QTreeWidgetItem* item, int column )
274 {
275  if ( column == 0 )
276  {
277  QColor color;
278 
279  QSettings settings;
280  //using native color dialogs?
281  bool useNative = settings.value( "/qgis/native_color_dialogs", false ).toBool();
282  if ( settings.value( "/qgis/live_color_dialogs", false ).toBool() )
283  {
284  mCurrentItem = item;
285  if ( useNative )
286  {
288  item->data( 0, StopColorRole ).value<QColor>(),
289  this, SLOT( setItemStopColor( const QColor& ) ),
290  this, tr( "Edit Stop Color" ), QColorDialog::ShowAlphaChannel );
291  }
292  else
293  {
295  item->data( 0, StopColorRole ).value<QColor>(), this, SLOT( setItemStopColor( const QColor& ) ),
296  this, tr( "Edit Stop Color" ), true );
297  }
298  mCurrentItem = 0;
299  }
300  else
301  {
302  color = QgsColorDialogV2::getColor( item->data( 0, StopColorRole ).value<QColor>(), this, tr( "Edit Stop Color" ), true );
303  }
304  if ( !color.isValid() )
305  return;
306  setStopColor( item, color );
307 
308  updatePreview();
309  }
310  else
311  {
312  bool ok;
313  double key = item->data( 0, StopOffsetRole ).toDouble();
314  // allow for floating-point values
315  double val = key * 100;
316  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
317  tr( "Please enter offset in percents (%) of the new stop" ),
318  val, 0, 100, 2, &ok );
319  if ( !ok )
320  return;
321 
322  double newkey = val / 100.0;
323  item->setText( 1, ( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
324  item->setData( 0, StopOffsetRole, newkey );
325 
326  updatePreview();
327  }
328 }
329 
331 {
332 // Native Mac dialog works only for Qt Carbon
333 // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889
334 // Qt 4.7 Mac Cocoa bug: calling QInputDialog::getInt after QColorDialog::getColor will freeze app
335 // workaround: call QColorDialog::getColor below instead of here,
336 // but not needed at this time because of the other Qt bug
337 // FIXME need to also check max QT_VERSION when Qt bug(s) fixed
338 #ifndef Q_OS_MAC
339  QColor color = QgsColorDialogV2::getColor( QColor(), this, tr( "Add Color Stop" ), true );
340 
341  if ( !color.isValid() )
342  return;
343  activateWindow();
344 #endif
345 
346  bool ok;
347  double val = 50.0;
348  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
349  tr( "Please enter offset in percents (%) of the new stop" ),
350  val, 0, 100, 2, &ok );
351  if ( !ok )
352  return;
353  activateWindow();
354 
355  double key = val / 100.0;
356  QStringList lst;
357  lst << "." << QString(( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
358 
359 #ifdef Q_OS_MAC
360  QColor color = QgsColorDialogV2::getColor( QColor(), this, tr( "Add Color Stop" ), true );
361 
362  if ( !color.isValid() )
363  return;
364  activateWindow();
365 #endif
366 
367  QTreeWidgetItem* item = new QTreeWidgetItem( lst );
368 
369  setStopColor( item, color );
370  item->setData( 0, StopOffsetRole, key );
371 
372  treeStops->addTopLevelItem( item );
373 
374  treeStops->resizeColumnToContents( 0 );
375  treeStops->setColumnWidth( 0, treeStops->columnWidth( 0 ) + 20 );
376 
377  updatePreview();
378 }
379 
381 {
382  QTreeWidgetItem* item = treeStops->currentItem();
383  if ( !item )
384  return;
385  int index = treeStops->indexOfTopLevelItem( item );
386  treeStops->takeTopLevelItem( index );
387 
388  updatePreview();
389 }
390 
392 {
393  Q_UNUSED( on );
394  updatePreview();
395 }
static unsigned index
static QPixmap colorRampPreviewPixmap(QgsVectorColorRampV2 *ramp, QSize size)
void setStopColor(QTreeWidgetItem *item, QColor color)
static QString defaultBaseDir()
A generic dialog with layout and button box.
Definition: qgsdialog.h:30
QMap< QString, QString > QgsStringMap
Definition: qgis.h:429
void setStops(const QgsGradientStopsList &stops)
QList< QgsGradientStop > QgsGradientStopsList
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), const bool allowAlpha=false)
Return a color selection from a color dialog.
const QgsGradientStopsList & stops() const
QgsVectorGradientColorRampV2Dialog(QgsVectorGradientColorRampV2 *ramp, QWidget *parent=NULL)
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition: qgsdialog.h:40
static QColor getLiveColor(const QColor &initialColor, QObject *updateObject, const char *updateSlot, QWidget *parent=0, const QString &title=QString(), const bool allowAlpha=true)
Return a color selection from a color dialog, with live updating of interim selections.
static QColor getLiveColor(const QColor &initialColor, QObject *updateObject, const char *updateSlot, QWidget *parent=0, const QString &title="", QColorDialog::ColorDialogOptions options=0)
Return a color selection from a QColorDialog, with live updating of interim selections.
void stopDoubleClicked(QTreeWidgetItem *item, int column)
#define tr(sourceText)