QGIS API Documentation  2.5.0-Master
 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 
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_WS_MAC
35  setWindowModality( Qt::WindowModal );
36 #endif
37 
38  btnColor1->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
39  btnColor1->setColorDialogTitle( tr( "Select ramp color" ) );
40  btnColor1->setContext( "symbology" );
41  btnColor1->setShowNoColor( true );
42  btnColor1->setNoColorString( tr( "Transparent" ) );
43  btnColor2->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
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;
103  for ( QgsStringMap::const_iterator it = mRamp->info().constBegin();
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 
178  QList<QTreeWidgetItem *> items;
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->setColor( mRamp->color1() );
222  btnColor2->setColor( mRamp->color2() );
223 }
224 
226 {
227  mRamp->setColor1( color );
228  updatePreview();
229 }
230 
232 {
233  mRamp->setColor2( color );
234  updatePreview();
235 }
236 
237 void QgsVectorGradientColorRampV2Dialog::setStopColor( QTreeWidgetItem* item, QColor color )
238 {
239  QSize iconSize( 16, 16 );
240  QPixmap pixmap( iconSize );
241  pixmap.fill( QColor( 0, 0, 0, 0 ) );
242  QRect rect( 1, 1, iconSize.width() - 2, iconSize.height() - 2 );
243 
244  // draw a slightly rounded rectangle
245  QPainter p;
246  p.begin( &pixmap );
247  p.setPen( Qt::NoPen );
248  p.setRenderHint( QPainter::Antialiasing );
249  p.setBrush( color );
250  p.drawRoundedRect( rect, 2, 2 );
251  p.end();
252 
253  item->setIcon( 0, QIcon( pixmap ) );
254  item->setData( 0, StopColorRole, color );
255  item->setText( 0, color.name() );
256 }
257 
259 {
260  if ( mCurrentItem )
261  {
262  setStopColor( mCurrentItem, newColor );
263  updatePreview();
264  }
265 }
266 
267 void QgsVectorGradientColorRampV2Dialog::stopDoubleClicked( QTreeWidgetItem* item, int column )
268 {
269  if ( column == 0 )
270  {
271  QColor color;
272 
273  QSettings settings;
274  if ( settings.value( "/qgis/live_color_dialogs", false ).toBool() )
275  {
276  mCurrentItem = item;
278  item->data( 0, StopColorRole ).value<QColor>(),
279  this, SLOT( setItemStopColor( const QColor& ) ),
280  this, tr( "Edit Stop Color" ), QColorDialog::ShowAlphaChannel );
281  mCurrentItem = 0;
282  }
283  else
284  {
285  color = QColorDialog::getColor( item->data( 0, StopColorRole ).value<QColor>(), this, tr( "Edit Stop Color" ), QColorDialog::ShowAlphaChannel );
286  }
287  if ( !color.isValid() )
288  return;
289  setStopColor( item, color );
290 
291  updatePreview();
292  }
293  else
294  {
295  bool ok;
296  double key = item->data( 0, StopOffsetRole ).toDouble();
297  // allow for floating-point values
298  double val = key * 100;
299  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
300  tr( "Please enter offset in percents (%) of the new stop" ),
301  val, 0, 100, 2, &ok );
302  if ( !ok )
303  return;
304 
305  double newkey = val / 100.0;
306  item->setText( 1, ( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
307  item->setData( 0, StopOffsetRole, newkey );
308 
309  updatePreview();
310  }
311 }
312 
314 {
315 // Native Mac dialog works only for Qt Carbon
316 // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889
317 // Qt 4.7 Mac Cocoa bug: calling QInputDialog::getInt after QColorDialog::getColor will freeze app
318 // workaround: call QColorDialog::getColor below instead of here,
319 // but not needed at this time because of the other Qt bug
320 // FIXME need to also check max QT_VERSION when Qt bug(s) fixed
321 #ifndef Q_WS_MAC
322  QColor color = QColorDialog::getColor( QColor(), this, tr( "Add Color Stop" ), QColorDialog::ShowAlphaChannel );
323 
324  if ( !color.isValid() )
325  return;
326  activateWindow();
327 #endif
328 
329  bool ok;
330  double val = 50.0;
331  val = QInputDialog::getDouble( this, tr( "Offset of the stop" ),
332  tr( "Please enter offset in percents (%) of the new stop" ),
333  val, 0, 100, 2, &ok );
334  if ( !ok )
335  return;
336  activateWindow();
337 
338  double key = val / 100.0;
339  QStringList lst;
340  lst << "." << QString(( val < 10 ) ? '0' + QString::number( val ) : QString::number( val ) );
341 
342 #ifdef Q_WS_MAC
343  QColor color = QColorDialog::getColor( QColor(), this, tr( "Add Color Stop" ), QColorDialog::ShowAlphaChannel );
344 
345  if ( !color.isValid() )
346  return;
347  activateWindow();
348 #endif
349 
350  QTreeWidgetItem* item = new QTreeWidgetItem( lst );
351 
352  setStopColor( item, color );
353  item->setData( 0, StopOffsetRole, key );
354 
355  treeStops->addTopLevelItem( item );
356 
357  treeStops->resizeColumnToContents( 0 );
358  treeStops->setColumnWidth( 0, treeStops->columnWidth( 0 ) + 20 );
359 
360  updatePreview();
361 }
362 
364 {
365  QTreeWidgetItem* item = treeStops->currentItem();
366  if ( !item )
367  return;
368  int index = treeStops->indexOfTopLevelItem( item );
369  treeStops->takeTopLevelItem( index );
370 
371  updatePreview();
372 }
373 
375 {
376  Q_UNUSED( on );
377  updatePreview();
378 }
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
void setStops(const QgsGradientStopsList &stops)
QString file
Definition: qgssvgcache.cpp:76
QList< QgsGradientStop > QgsGradientStopsList
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
double size
Definition: qgssvgcache.cpp:77
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)