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