|
| 1 | +/*************************************************************************** |
| 2 | + qgssymbolslist.cpp |
| 3 | + --------------------- |
| 4 | + begin : June 2012 |
| 5 | + copyright : (C) 2012 by Arunmozhi |
| 6 | + email : aruntheguy at gmail.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 | + |
| 16 | + |
| 17 | +#include "qgssymbolslistwidget.h" |
| 18 | + |
| 19 | +#include "qgsstylev2managerdialog.h" |
| 20 | + |
| 21 | +#include "qgssymbolv2.h" |
| 22 | +#include "qgsstylev2.h" |
| 23 | +#include "qgssymbollayerv2utils.h" |
| 24 | + |
| 25 | +#include "qgsapplication.h" |
| 26 | + |
| 27 | +#include <QString> |
| 28 | +#include <QStringList> |
| 29 | +#include <QPainter> |
| 30 | +#include <QIcon> |
| 31 | +#include <QStandardItemModel> |
| 32 | +#include <QColorDialog> |
| 33 | +#include <QInputDialog> |
| 34 | +#include <QMessageBox> |
| 35 | +#include <QMenu> |
| 36 | + |
| 37 | + |
| 38 | +QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QWidget* parent ) : QWidget( parent ) |
| 39 | +{ |
| 40 | + mSymbol = symbol; |
| 41 | + mStyle = style; |
| 42 | + |
| 43 | + setupUi( this ); |
| 44 | + |
| 45 | + btnAdvanced->hide(); // advanced button is hidden by default |
| 46 | + |
| 47 | + QStandardItemModel* model = new QStandardItemModel( viewSymbols ); |
| 48 | + viewSymbols->setModel( model ); |
| 49 | + //connect( viewSymbols, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) ); |
| 50 | + |
| 51 | + connect( btnStyleManager, SIGNAL( clicked() ), SLOT( openStyleManager() ) ); |
| 52 | + lblSymbolName->setText( "" ); |
| 53 | + populateSymbolView(); |
| 54 | + |
| 55 | + if ( mSymbol ) |
| 56 | + { |
| 57 | + // output unit |
| 58 | + mSymbolUnitComboBox->blockSignals( true ); |
| 59 | + mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() ); |
| 60 | + mSymbolUnitComboBox->blockSignals( false ); |
| 61 | + |
| 62 | + mTransparencySlider->blockSignals( true ); |
| 63 | + double transparency = 1 - symbol->alpha(); |
| 64 | + mTransparencySlider->setValue( transparency * 255 ); |
| 65 | + displayTransparency( symbol->alpha() ); |
| 66 | + mTransparencySlider->blockSignals( false ); |
| 67 | + } |
| 68 | + |
| 69 | + // select correct page in stacked widget |
| 70 | + // there's a correspondence between symbol type number and page numbering => exploit it! |
| 71 | + stackedWidget->setCurrentIndex( symbol->type() ); |
| 72 | + connect( btnColor, SIGNAL( clicked() ), this, SLOT( setSymbolColor() ) ); |
| 73 | + connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) ); |
| 74 | + connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) ); |
| 75 | + connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) ); |
| 76 | + |
| 77 | + connect( btnAddToStyle, SIGNAL( clicked() ), this, SLOT( addSymbolToStyle() ) ); |
| 78 | + btnAddToStyle->setIcon( QIcon( QgsApplication::defaultThemePath() + "symbologyAdd.png" ) ); |
| 79 | + |
| 80 | +} |
| 81 | + |
| 82 | + |
| 83 | +void QgsSymbolsListWidget::populateSymbolView() |
| 84 | +{ |
| 85 | + QSize previewSize = viewSymbols->iconSize(); |
| 86 | + QPixmap p( previewSize ); |
| 87 | + QPainter painter; |
| 88 | + |
| 89 | + QStandardItemModel* model = qobject_cast<QStandardItemModel*>( viewSymbols->model() ); |
| 90 | + if ( !model ) |
| 91 | + { |
| 92 | + return; |
| 93 | + } |
| 94 | + model->clear(); |
| 95 | + |
| 96 | + QStringList names = mStyle->symbolNames(); |
| 97 | + for ( int i = 0; i < names.count(); i++ ) |
| 98 | + { |
| 99 | + QgsSymbolV2* s = mStyle->symbol( names[i] ); |
| 100 | + if ( s->type() != mSymbol->type() ) |
| 101 | + { |
| 102 | + delete s; |
| 103 | + continue; |
| 104 | + } |
| 105 | + QStandardItem* item = new QStandardItem( names[i] ); |
| 106 | + item->setData( names[i], Qt::UserRole ); //so we can show a label when it is clicked |
| 107 | + item->setText( "" ); //set the text to nothing and show in label when clicked rather |
| 108 | + item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); |
| 109 | + // create preview icon |
| 110 | + QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize ); |
| 111 | + item->setIcon( icon ); |
| 112 | + // add to model |
| 113 | + model->appendRow( item ); |
| 114 | + delete s; |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +void QgsSymbolsListWidget::openStyleManager() |
| 119 | +{ |
| 120 | + QgsStyleV2ManagerDialog dlg( mStyle, this ); |
| 121 | + dlg.exec(); |
| 122 | + |
| 123 | + populateSymbolView(); |
| 124 | +} |
| 125 | + |
| 126 | +void QgsSymbolsListWidget::setSymbolColor() |
| 127 | +{ |
| 128 | +#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && defined(QT_MAC_USE_COCOA) |
| 129 | + // Native Mac dialog works only for Qt Carbon |
| 130 | + // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889 |
| 131 | + // FIXME need to also check max QT_VERSION when Qt bug fixed |
| 132 | + QColor color = QColorDialog::getColor( mSymbol->color(), this, "", QColorDialog::DontUseNativeDialog ); |
| 133 | +#else |
| 134 | + QColor color = QColorDialog::getColor( mSymbol->color(), this ); |
| 135 | +#endif |
| 136 | + if ( !color.isValid() ) |
| 137 | + return; |
| 138 | + |
| 139 | + mSymbol->setColor( color ); |
| 140 | + updateSymbolColor(); |
| 141 | + emit changed(); |
| 142 | +} |
| 143 | + |
| 144 | +void QgsSymbolsListWidget::setMarkerAngle( double angle ) |
| 145 | +{ |
| 146 | + QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol ); |
| 147 | + if ( markerSymbol->angle() == angle ) |
| 148 | + return; |
| 149 | + markerSymbol->setAngle( angle ); |
| 150 | + emit changed(); |
| 151 | +} |
| 152 | + |
| 153 | +void QgsSymbolsListWidget::setMarkerSize( double size ) |
| 154 | +{ |
| 155 | + QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol ); |
| 156 | + if ( markerSymbol->size() == size ) |
| 157 | + return; |
| 158 | + markerSymbol->setSize( size ); |
| 159 | + emit changed(); |
| 160 | +} |
| 161 | + |
| 162 | +void QgsSymbolsListWidget::setLineWidth( double width ) |
| 163 | +{ |
| 164 | + QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol ); |
| 165 | + if ( lineSymbol->width() == width ) |
| 166 | + return; |
| 167 | + lineSymbol->setWidth( width ); |
| 168 | + emit changed(); |
| 169 | +} |
| 170 | + |
| 171 | +void QgsSymbolsListWidget::addSymbolToStyle() |
| 172 | +{ |
| 173 | + bool ok; |
| 174 | + QString name = QInputDialog::getText( this, tr( "Symbol name" ), |
| 175 | + tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok ); |
| 176 | + if ( !ok || name.isEmpty() ) |
| 177 | + return; |
| 178 | + |
| 179 | + // check if there is no symbol with same name |
| 180 | + if ( mStyle->symbolNames().contains( name ) ) |
| 181 | + { |
| 182 | + int res = QMessageBox::warning( this, tr( "Save symbol" ), |
| 183 | + tr( "Symbol with name '%1' already exists. Overwrite?" ) |
| 184 | + .arg( name ), |
| 185 | + QMessageBox::Yes | QMessageBox::No ); |
| 186 | + if ( res != QMessageBox::Yes ) |
| 187 | + { |
| 188 | + return; |
| 189 | + } |
| 190 | + } |
| 191 | + |
| 192 | + // add new symbol to style and re-populate the list |
| 193 | + mStyle->addSymbol( name, mSymbol->clone() ); |
| 194 | + |
| 195 | + // make sure the symbol is stored |
| 196 | + mStyle->save(); |
| 197 | + |
| 198 | + populateSymbolView(); |
| 199 | +} |
| 200 | + |
| 201 | +void QgsSymbolsListWidget::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text ) |
| 202 | +{ |
| 203 | + Q_UNUSED( text ); |
| 204 | + if ( mSymbol ) |
| 205 | + { |
| 206 | + mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() ); |
| 207 | + |
| 208 | + emit changed(); |
| 209 | + } |
| 210 | +} |
| 211 | + |
| 212 | +void QgsSymbolsListWidget::on_mTransparencySlider_valueChanged( int value ) |
| 213 | +{ |
| 214 | + if ( mSymbol ) |
| 215 | + { |
| 216 | + double alpha = 1 - ( value / 255.0 ); |
| 217 | + mSymbol->setAlpha( alpha ); |
| 218 | + displayTransparency( alpha ); |
| 219 | + emit changed(); |
| 220 | + } |
| 221 | +} |
| 222 | + |
| 223 | +void QgsSymbolsListWidget::displayTransparency( double alpha ) |
| 224 | +{ |
| 225 | + double transparencyPercent = ( 1 - alpha ) * 100; |
| 226 | + mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) ); |
| 227 | +} |
| 228 | + |
| 229 | +void QgsSymbolsListWidget::updateSymbolColor() |
| 230 | +{ |
| 231 | + btnColor->setColor( mSymbol->color() ); |
| 232 | +} |
| 233 | + |
| 234 | +void QgsSymbolsListWidget::updateSymbolInfo() |
| 235 | +{ |
| 236 | + updateSymbolColor(); |
| 237 | + |
| 238 | + if ( mSymbol->type() == QgsSymbolV2::Marker ) |
| 239 | + { |
| 240 | + QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol ); |
| 241 | + spinSize->setValue( markerSymbol->size() ); |
| 242 | + spinAngle->setValue( markerSymbol->angle() ); |
| 243 | + } |
| 244 | + else if ( mSymbol->type() == QgsSymbolV2::Line ) |
| 245 | + { |
| 246 | + QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol ); |
| 247 | + spinWidth->setValue( lineSymbol->width() ); |
| 248 | + } |
| 249 | +} |
| 250 | + |
| 251 | +void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index ) |
| 252 | +{ |
| 253 | + QString symbolName = index.data( Qt::UserRole ).toString(); |
| 254 | + lblSymbolName->setText( symbolName ); |
| 255 | + // get new instance of symbol from style |
| 256 | + QgsSymbolV2* s = mStyle->symbol( symbolName ); |
| 257 | + // remove all symbol layers from original symbol |
| 258 | + while ( mSymbol->symbolLayerCount() ) |
| 259 | + mSymbol->deleteSymbolLayer( 0 ); |
| 260 | + // move all symbol layers to our symbol |
| 261 | + while ( s->symbolLayerCount() ) |
| 262 | + { |
| 263 | + QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 ); |
| 264 | + mSymbol->appendSymbolLayer( sl ); |
| 265 | + } |
| 266 | + // delete the temporary symbol |
| 267 | + delete s; |
| 268 | + |
| 269 | + updateSymbolInfo(); |
| 270 | + emit changed(); |
| 271 | +} |
| 272 | + |
| 273 | + |
| 274 | + |
| 275 | + |
| 276 | + |
| 277 | + |
0 commit comments