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