QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 #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  for ( QgsStringMap::const_iterator it = mRamp->info().constBegin();
105  it != mRamp->info().constEnd(); ++it )
106  {
107  if ( it.key().startsWith( "cpt-city" ) )
108  continue;
109  tableInfo->setItem( i, 0, new QTableWidgetItem( it.key() ) );
110  tableInfo->setItem( i, 1, new QTableWidgetItem( it.value() ) );
111  tableInfo->resizeRowToContents( i );
112  i++;
113  }
114  tableInfo->resizeColumnToContents( 0 );
115  tableInfo->horizontalHeader()->setStretchLastSection( true );
116  tableInfo->setRowCount( i );
117  tableInfo->setFixedHeight( tableInfo->rowHeight( 0 ) * i + 5 );
118  dlg->layout()->addWidget( tableInfo );
119  dlg->resize( 600, 250 );
120 
121  dlg->layout()->addSpacing( 5 );
122 
123  // gradient file
124  QString gradientFile = mRamp->info().value( "cpt-city-gradient" );
125  if ( ! gradientFile.isNull() )
126  {
127  QString fileName = gradientFile;
128  fileName.replace( "<cpt-city>", QgsCptCityArchive::defaultBaseDir() );
129  if ( ! QFile::exists( fileName ) )
130  {
131  fileName = gradientFile;
132  fileName.replace( "<cpt-city>", "http://soliton.vm.bytemark.co.uk/pub/cpt-city" );
133  }
134  label = new QLabel( tr( "Gradient file : %1" ).arg( fileName ), dlg );
135  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
136  dlg->layout()->addSpacing( 5 );
137  dlg->layout()->addWidget( label );
138  }
139 
140  // license file
141  QString licenseFile = mRamp->info().value( "cpt-city-license" );
142  if ( !licenseFile.isNull() )
143  {
144  QString fileName = licenseFile;
145  fileName.replace( "<cpt-city>", QgsCptCityArchive::defaultBaseDir() );
146  if ( ! QFile::exists( fileName ) )
147  {
148  fileName = licenseFile;
149  fileName.replace( "<cpt-city>", "http://soliton.vm.bytemark.co.uk/pub/cpt-city" );
150  }
151  label = new QLabel( tr( "License file : %1" ).arg( fileName ), dlg );
152  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
153  dlg->layout()->addSpacing( 5 );
154  dlg->layout()->addWidget( label );
155  if ( QFile::exists( fileName ) )
156  {
157  QTextEdit *textEdit = new QTextEdit( dlg );
158  textEdit->setReadOnly( true );
159  QFile file( fileName );
160  if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
161  {
162  textEdit->setText( file.readAll() );
163  file.close();
164  dlg->layout()->addSpacing( 5 );
165  dlg->layout()->addWidget( textEdit );
166  dlg->resize( 600, 500 );
167  }
168  }
169  }
170 
171  dlg->show(); //non modal
172 }
173 
175 {
176  QgsGradientStopsList stops = mRamp->stops();
177  groupStops->setChecked( !stops.isEmpty() );
178 
179  QList<QTreeWidgetItem *> items;
180  for ( QgsGradientStopsList::iterator it = stops.begin();
181  it != stops.end(); ++it )
182  {
183  double val = it->offset * 100.0;
184  QStringList lst;
185  lst << "." << QString(( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
186  QTreeWidgetItem* item = new QTreeWidgetItem( lst );
187 
188  setStopColor( item, it->color );
189  item->setData( 0, StopOffsetRole, it->offset );
190 
191  items.append( item );
192  }
193  treeStops->clear();
194  treeStops->insertTopLevelItems( 0, items );
195  treeStops->resizeColumnToContents( 0 );
196  treeStops->setColumnWidth( 0, treeStops->columnWidth( 0 ) + 20 );
197  treeStops->sortByColumn( 1, Qt::AscendingOrder );
198  treeStops->setSortingEnabled( true );
199 }
200 
202 {
203  // update ramp stops from the tree widget
204  QgsGradientStopsList stops;
205  if ( groupStops->isChecked() )
206  {
207  int count = treeStops->topLevelItemCount();
208  for ( int i = 0; i < count; i++ )
209  {
210  QTreeWidgetItem* item = treeStops->topLevelItem( i );
211  double offset = item->data( 0, StopOffsetRole ).toDouble();
212  QColor color = item->data( 0, StopColorRole ).value<QColor>();
213  stops.append( QgsGradientStop( offset, color ) );
214  }
215  }
216  mRamp->setStops( stops );
217 
218  // generate the preview
219  QSize size( 300, 40 );
220  lblPreview->setPixmap( QgsSymbolLayerV2Utils::colorRampPreviewPixmap( mRamp, size ) );
221 
222  btnColor1->blockSignals( true );
223  btnColor1->setColor( mRamp->color1() );
224  btnColor1->blockSignals( false );
225  btnColor2->blockSignals( true );
226  btnColor2->setColor( mRamp->color2() );
227  btnColor2->blockSignals( false );
228 }
229 
231 {
232  mRamp->setColor1( color );
233  updatePreview();
234 }
235 
237 {
238  mRamp->setColor2( color );
239  updatePreview();
240 }
241 
242 void QgsVectorGradientColorRampV2Dialog::setStopColor( QTreeWidgetItem* item, QColor color )
243 {
244  QSize iconSize( 16, 16 );
245  QPixmap pixmap( iconSize );
246  pixmap.fill( QColor( 0, 0, 0, 0 ) );
247  QRect rect( 1, 1, iconSize.width() - 2, iconSize.height() - 2 );
248 
249  // draw a slightly rounded rectangle
250  QPainter p;
251  p.begin( &pixmap );
252  p.setPen( Qt::NoPen );
253  p.setRenderHint( QPainter::Antialiasing );
254  p.setBrush( color );
255  p.drawRoundedRect( rect, 2, 2 );
256  p.end();
257 
258  item->setIcon( 0, QIcon( pixmap ) );
259  item->setData( 0, StopColorRole, color );
260  item->setText( 0, color.name() );
261 }
262 
264 {
265  if ( mCurrentItem )
266  {
267  setStopColor( mCurrentItem, newColor );
268  updatePreview();
269  }
270 }
271 
272 void QgsVectorGradientColorRampV2Dialog::stopDoubleClicked( QTreeWidgetItem* item, int column )
273 {
274  if ( column == 0 )
275  {
276  QColor color;
277 
278  QSettings settings;
279  //using native color dialogs?
280  bool useNative = settings.value( "/qgis/native_color_dialogs", false ).toBool();
281  if ( settings.value( "/qgis/live_color_dialogs", false ).toBool() )
282  {
283  mCurrentItem = item;
284  if ( useNative )
285  {
287  item->data( 0, StopColorRole ).value<QColor>(),
288  this, SLOT( setItemStopColor( const QColor& ) ),
289  this, tr( "Edit Stop Color" ), QColorDialog::ShowAlphaChannel );
290  }
291  else
292  {
294  item->data( 0, StopColorRole ).value<QColor>(), this, SLOT( setItemStopColor( const QColor& ) ),
295  this, tr( "Edit Stop Color" ), true );
296  }
297  mCurrentItem = 0;
298  }
299  else
300  {
301  color = QgsColorDialogV2::getColor( item->data( 0, StopColorRole ).value<QColor>(), this, tr( "Edit Stop Color" ), true );
302  }
303  if ( !color.isValid() )
304  return;
305  setStopColor( item, color );
306 
307  updatePreview();
308  }
309  else
310  {
311  bool ok;
312  double key = item->data( 0, StopOffsetRole ).toDouble();
313  // allow for floating-point values
314  double val = key * 100;
315  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
316  tr( "Please enter offset in percents (%) of the new stop" ),
317  val, 0, 100, 2, &ok );
318  if ( !ok )
319  return;
320 
321  double newkey = val / 100.0;
322  item->setText( 1, ( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
323  item->setData( 0, StopOffsetRole, newkey );
324 
325  updatePreview();
326  }
327 }
328 
330 {
331 // Native Mac dialog works only for Qt Carbon
332 // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889
333 // Qt 4.7 Mac Cocoa bug: calling QInputDialog::getInt after QColorDialog::getColor will freeze app
334 // workaround: call QColorDialog::getColor below instead of here,
335 // but not needed at this time because of the other Qt bug
336 // FIXME need to also check max QT_VERSION when Qt bug(s) fixed
337 #ifndef Q_OS_MAC
338  QColor color = QgsColorDialogV2::getColor( QColor(), this, tr( "Add Color Stop" ), true );
339 
340  if ( !color.isValid() )
341  return;
342  activateWindow();
343 #endif
344 
345  bool ok;
346  double val = 50.0;
347  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
348  tr( "Please enter offset in percents (%) of the new stop" ),
349  val, 0, 100, 2, &ok );
350  if ( !ok )
351  return;
352  activateWindow();
353 
354  double key = val / 100.0;
355  QStringList lst;
356  lst << "." << QString(( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
357 
358 #ifdef Q_OS_MAC
359  QColor color = QgsColorDialogV2::getColor( QColor(), this, tr( "Add Color Stop" ), true );
360 
361  if ( !color.isValid() )
362  return;
363  activateWindow();
364 #endif
365 
366  QTreeWidgetItem* item = new QTreeWidgetItem( lst );
367 
368  setStopColor( item, color );
369  item->setData( 0, StopOffsetRole, key );
370 
371  treeStops->addTopLevelItem( item );
372 
373  treeStops->resizeColumnToContents( 0 );
374  treeStops->setColumnWidth( 0, treeStops->columnWidth( 0 ) + 20 );
375 
376  updatePreview();
377 }
378 
380 {
381  QTreeWidgetItem* item = treeStops->currentItem();
382  if ( !item )
383  return;
384  int index = treeStops->indexOfTopLevelItem( item );
385  treeStops->takeTopLevelItem( index );
386 
387  updatePreview();
388 }
389 
391 {
392  Q_UNUSED( on );
393  updatePreview();
394 }