25 #include <QTemporaryFile>
26 #include <QMouseEvent>
30 #include <QDesktopWidget>
34 QString QgsColorButton::fullPath(
const QString &path )
37 int len = GetLongPathName( path.toUtf8().constData(), buf, MAX_PATH );
39 if ( len == 0 || len > MAX_PATH )
41 QgsDebugMsg( QString(
"GetLongPathName('%1') failed with %2: %3" )
42 .arg( path ).arg( len ).arg( GetLastError() ) );
46 QString res = QString::fromUtf8( buf );
68 : QPushButton( parent )
69 , mColorDialogTitle( cdt.isEmpty() ?
tr(
"Select Color" ) : cdt )
71 , mColorDialogOptions( cdo )
72 , mAcceptLiveUpdates( true )
75 , mPickingColor( false )
77 setAcceptDrops(
true );
78 connect(
this, SIGNAL( clicked() ),
this, SLOT( onButtonClicked() ) );
83 if ( mTempPNG.exists() )
91 if ( transpBkgrd.isNull() )
97 void QgsColorButton::onButtonClicked()
103 bool useNative = settings.value(
"/qgis/native_color_dialogs",
false ).toBool();
107 if ( mAcceptLiveUpdates && settings.value(
"/qgis/live_color_dialogs",
false ).toBool() )
110 color(),
this, SLOT( setValidColor(
const QColor& ) ),
111 this->parentWidget(), mColorDialogTitle, mColorDialogOptions );
115 newColor = QColorDialog::getColor(
color(), this->parentWidget(), mColorDialogTitle, mColorDialogOptions );
121 if ( mAcceptLiveUpdates && settings.value(
"/qgis/live_color_dialogs",
false ).toBool() )
124 color(),
this, SLOT( setValidColor(
const QColor& ) ),
125 this->parentWidget(), mColorDialogTitle, mColorDialogOptions & QColorDialog::ShowAlphaChannel );
130 dialog.setTitle( mColorDialogTitle );
131 dialog.setAllowAlpha( mColorDialogOptions & QColorDialog::ShowAlphaChannel );
135 newColor = dialog.color();
140 if ( newColor.isValid() )
142 setValidColor( newColor );
158 if ( e->button() == Qt::RightButton )
160 showContextMenu( e );
163 else if ( e->button() == Qt::LeftButton )
165 mDragStartPosition = e->pos();
170 QMimeData * QgsColorButton::createColorMimeData()
const
172 QMimeData *mimeData =
new QMimeData;
173 mimeData->setColorData( QVariant( mColor ) );
174 mimeData->setText( mColor.name() );
178 bool QgsColorButton::colorFromMimeData(
const QMimeData * mimeData, QColor& resultColor )
181 QColor mimeColor = mimeData->colorData().value<QColor>();
182 if ( mimeColor.isValid() )
184 if ( !( mColorDialogOptions & QColorDialog::ShowAlphaChannel ) )
187 mimeColor.setAlpha( 255 );
189 resultColor = mimeColor;
194 bool hasAlpha =
false;
196 if ( textColor.isValid() )
198 if ( !( mColorDialogOptions & QColorDialog::ShowAlphaChannel ) )
201 textColor.setAlpha( 255 );
203 else if ( !hasAlpha )
206 textColor.setAlpha( mColor.alpha() );
208 resultColor = textColor;
221 if ( e->buttons() & Qt::LeftButton )
225 QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), e->globalPos().x(), e->globalPos().y(), 1, 1 );
226 QImage snappedImage = snappedPixmap.toImage();
227 QColor hoverColor = snappedImage.pixel( 0, 0 );
235 if ( !( e->buttons() & Qt::LeftButton ) )
241 if (( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
247 QDrag *drag =
new QDrag(
this );
248 drag->setMimeData( createColorMimeData() );
251 QImage colorImage( 50, 50, QImage::Format_RGB32 );
252 QPainter imagePainter;
253 imagePainter.begin( &colorImage );
255 imagePainter.fillRect( QRect( 0, 0, 50, 50 ), QBrush( QColor( 200, 200, 200 ) ) );
257 QColor pixmapColor = mColor;
258 pixmapColor.setAlpha( 255 );
259 imagePainter.setBrush( QBrush( pixmapColor ) );
260 imagePainter.setPen( QPen( Qt::white ) );
261 imagePainter.drawRect( QRect( 1, 1, 47, 47 ) );
264 drag->setPixmap( QPixmap::fromImage( colorImage ) );
266 drag->exec( Qt::CopyAction );
275 stopPicking( e->globalPos() );
283 void QgsColorButton::stopPicking( QPointF eventPos,
bool sampleColor )
288 mPickingColor =
false;
297 QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), eventPos.x(), eventPos.y(), 1, 1 );
298 QImage snappedImage = snappedPixmap.toImage();
300 setColor( snappedImage.pixel( 0, 0 ) );
305 if ( !mPickingColor )
313 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
320 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
322 e->acceptProposedAction();
330 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
332 e->acceptProposedAction();
337 void QgsColorButton::showContextMenu( QMouseEvent *event )
339 QMenu colorContextMenu;
341 QAction* copyColorAction =
new QAction(
tr(
"Copy color" ), 0 );
342 colorContextMenu.addAction( copyColorAction );
343 QAction* pasteColorAction =
new QAction(
tr(
"Paste color" ), 0 );
344 pasteColorAction->setEnabled(
false );
345 colorContextMenu.addAction( pasteColorAction );
350 QAction* pickColorAction =
new QAction(
tr(
"Pick color" ), 0 );
351 colorContextMenu.addSeparator();
352 colorContextMenu.addAction( pickColorAction );
356 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
358 pasteColorAction->setEnabled(
true );
361 QAction* selectedAction = colorContextMenu.exec( event->globalPos() );
362 if ( selectedAction == copyColorAction )
365 QApplication::clipboard()->setMimeData( createColorMimeData() );
367 else if ( selectedAction == pasteColorAction )
373 else if ( selectedAction == pickColorAction )
376 QPixmap samplerPixmap = QPixmap((
const char ** )
sampler_cursor );
377 setCursor( QCursor( samplerPixmap, 0, 0 ) );
379 mPickingColor =
true;
381 delete pickColorAction;
384 delete copyColorAction;
385 delete pasteColorAction;
388 void QgsColorButton::setValidColor(
const QColor& newColor )
390 if ( newColor.isValid() )
398 if ( e->type() == QEvent::EnabledChange )
405 #if 0 // causes too many cyclical updates, but may be needed on some platforms
406 void QgsColorButton::paintEvent( QPaintEvent* e )
408 QPushButton::paintEvent( e );
410 if ( !mBackgroundSet )
425 if ( !color.isValid() )
429 QColor oldColor = mColor;
433 if ( oldColor != mColor || ( mColor == QColor( Qt::black ) && !mColorSet ) )
448 if ( !color.isValid() )
452 if ( !text().isEmpty() )
458 pixmap = QPixmap( iconSize() );
459 pixmap.fill( QColor( 0, 0, 0, 0 ) );
461 int iconW = iconSize().width();
462 int iconH = iconSize().height();
463 QRect rect( 0, 0, iconW, iconH );
466 QPainterPath roundRect;
469 roundRect.moveTo( chamfer, inset );
470 roundRect.lineTo( iconW - chamfer, inset );
471 roundRect.lineTo( iconW - inset, chamfer );
472 roundRect.lineTo( iconW - inset, iconH - chamfer );
473 roundRect.lineTo( iconW - chamfer, iconH - inset );
474 roundRect.lineTo( chamfer, iconH - inset );
475 roundRect.lineTo( inset, iconH - chamfer );
476 roundRect.lineTo( inset, chamfer );
477 roundRect.closeSubpath();
481 p.setRenderHint( QPainter::Antialiasing );
482 p.setClipPath( roundRect );
483 p.setPen( Qt::NoPen );
484 if ( color.alpha() < 255 )
493 setIcon( QIcon( pixmap ) );
502 bool useAlpha = ( mColorDialogOptions & QColorDialog::ShowAlphaChannel );
505 QString margin = QString(
"%1px %2px %3px %4px" ).arg( 0 ).arg( 0 ).arg( 0 ).arg( 0 );
509 QString bkgrd = QString(
" background-color: rgba(%1,%2,%3,%4);" )
511 .arg( color.green() )
513 .arg( useAlpha ? color.alpha() : 255 );
515 if ( useAlpha && color.alpha() < 255 )
518 QRect rect( 0, 0, pixmap.width(), pixmap.height() );
522 p.setRenderHint( QPainter::Antialiasing );
523 p.setPen( Qt::NoPen );
524 p.setBrush( mColor );
528 if ( mTempPNG.open() )
530 mTempPNG.setAutoRemove(
false );
531 pixmap.save( mTempPNG.fileName(),
"PNG" );
535 QString bgFileName = mTempPNG.fileName();
539 bgFileName = fullPath( bgFileName );
541 bkgrd = QString(
" background-image: url(%1);" ).arg( bgFileName );
545 setStyleSheet( QString(
"QgsColorButton{"
547 " background-position: top left;"
548 " background-origin: content;"
549 " background-clip: content;"
554 " border-width: 1px;"
555 " border-color: rgb(%3,%3,%3);"
556 " border-radius: 3px;} "
557 "QgsColorButton:pressed{"
559 " background-position: top left;"
560 " background-origin: content;"
561 " background-clip: content;"
565 " border-style: inset;"
566 " border-width: 2px;"
567 " border-color: rgb(128,128,128);"
568 " border-radius: 4px;} " )
571 .arg( isEnabled() ?
"128" :
"110" )
572 .arg( isEnabled() ?
"outset" :
"dotted" ) );
583 mColorDialogOptions = cdo;
588 return mColorDialogOptions;
593 mColorDialogTitle = cdt;
598 return mColorDialogTitle;