File indexing completed on 2024-05-05 04:49:29
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Téo Mrnjavac <teo@kde.org> * 0003 * Copyright (c) 2008-2009 Seb Ruiz <ruiz@kde.org> * 0004 * Copyright (c) 2009 Roman Jarosz <kedgedev@gmail.com> * 0005 * Copyright (c) 2009 Daniel Dewald <Daniel.Dewald@time-shift.de> * 0006 * Copyright (c) 2012 Ralf Engels <ralf-engels@gmx.de> * 0007 * * 0008 * This program is free software; you can redistribute it and/or modify it under * 0009 * the terms of the GNU General Public License as published by the Free Software * 0010 * Foundation; either version 2 of the License, or (at your option) any later * 0011 * version. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0014 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0015 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License along with * 0018 * this program. If not, see <http://www.gnu.org/licenses/>. * 0019 ****************************************************************************************/ 0020 0021 #include "Token.h" 0022 #include "TokenDropTarget.h" 0023 0024 #include <QApplication> 0025 0026 #include <QHBoxLayout> 0027 #include <QPainter> 0028 #include <QPen> 0029 0030 #include <QPixmap> 0031 #include <QMimeData> 0032 #include <QMouseEvent> 0033 #include <QDrag> 0034 0035 0036 Token* 0037 TokenFactory::createToken(const QString & text, const QString & iconName, qint64 value, QWidget * parent) const 0038 { 0039 return new Token( text, iconName, value, parent ); 0040 } 0041 0042 Token* 0043 TokenFactory::createTokenFromMime( const QMimeData* mimeData, QWidget* parent ) const 0044 { 0045 // decode the stream created in Token::mimeData 0046 QByteArray itemData = mimeData->data( Token::mimeType() ); 0047 QDataStream dataStream(&itemData, QIODevice::ReadOnly); 0048 0049 QString tokenName; 0050 QString tokenIconName; 0051 qint64 tokenValue; 0052 QColor tokenTextColor; 0053 0054 dataStream >> tokenName; 0055 dataStream >> tokenIconName; 0056 dataStream >> tokenValue; 0057 dataStream >> tokenTextColor; 0058 0059 Token* token = createToken( tokenName, tokenIconName, tokenValue, parent ); 0060 token->setTextColor( tokenTextColor ); 0061 0062 return token; 0063 } 0064 0065 0066 Token::Token( const QString &name, const QString &iconName, qint64 value, QWidget *parent ) 0067 : QWidget( parent ) 0068 , m_name( name ) 0069 , m_icon( QIcon::fromTheme( iconName ) ) 0070 , m_iconName( iconName ) 0071 , m_value( value ) 0072 , m_customColor( false ) 0073 { 0074 setFocusPolicy( Qt::StrongFocus ); 0075 0076 // Note: We set all the margins because we need a quite small size. 0077 // Vertically for the EditPlaylistLayoutDialog and horizontally for 0078 // the OrganizeTracksDialog 0079 0080 m_label = new QLabel( this ); 0081 m_label->setAlignment( Qt::AlignCenter ); 0082 m_label->setContentsMargins( 0, 0, 0, 0 ); 0083 m_label->setMargin( 0 ); 0084 m_label->setText( name ); 0085 0086 m_iconContainer = new QLabel( this ); 0087 m_iconContainer->setContentsMargins( 0, 0, 0, 0 ); 0088 m_iconContainer->setMargin( 0 ); 0089 QPixmap pixmap = QPixmap( icon().pixmap( 16, 16 ) ); 0090 m_iconContainer->setPixmap( pixmap ); 0091 0092 QHBoxLayout *hlayout = new QHBoxLayout( this ); 0093 hlayout->setSpacing( 3 ); 0094 hlayout->setContentsMargins( 3, 0, 3, 0 ); // to allow the label to overwrite the border if space get's tight 0095 hlayout->addWidget( m_iconContainer ); 0096 hlayout->addWidget( m_label ); 0097 setLayout( hlayout ); 0098 0099 updateCursor(); 0100 } 0101 0102 QString 0103 Token::name() const 0104 { 0105 return m_name; 0106 } 0107 0108 qint64 0109 Token::value() const 0110 { 0111 return m_value; 0112 } 0113 0114 QIcon 0115 Token::icon() const 0116 { 0117 return m_icon; 0118 } 0119 0120 QString Token::iconName() const 0121 { 0122 return m_iconName; 0123 } 0124 0125 QColor Token::textColor() const 0126 { 0127 return m_label->palette().color( QPalette::WindowText ); 0128 } 0129 0130 void 0131 Token::setTextColor( QColor textColor ) 0132 { 0133 m_customColor = true; 0134 if( textColor == this->textColor() ) 0135 return; 0136 QPalette myPalette( m_label->palette() ); 0137 myPalette.setColor( QPalette::WindowText, textColor ); 0138 m_label->setPalette( myPalette ); 0139 } 0140 0141 QMimeData* 0142 Token::mimeData() const 0143 { 0144 QByteArray itemData; 0145 0146 QDataStream dataStream( &itemData, QIODevice::WriteOnly ); 0147 dataStream << name() << iconName() << value() << textColor(); 0148 0149 QMimeData *mimeData = new QMimeData; 0150 mimeData->setData( mimeType(), itemData ); 0151 0152 return mimeData; 0153 } 0154 0155 QString 0156 Token::mimeType() 0157 { 0158 return QLatin1String( "application/x-amarok-tag-token" ); 0159 } 0160 0161 QSize 0162 Token::sizeHint() const 0163 { 0164 QSize result = QWidget::sizeHint(); 0165 result += QSize( 6, 6 ); // the border 0166 0167 return result; 0168 } 0169 0170 QSize 0171 Token::minimumSizeHint() const 0172 { 0173 QSize result = QWidget::minimumSizeHint(); 0174 0175 return result; 0176 } 0177 0178 void 0179 Token::changeEvent( QEvent *event ) 0180 { 0181 QWidget::changeEvent( event ); 0182 if( !event || event->type() == QEvent::EnabledChange ) 0183 updateCursor(); 0184 } 0185 0186 void 0187 Token::focusInEvent( QFocusEvent* event ) 0188 { 0189 QWidget::focusInEvent( event ); 0190 Q_EMIT gotFocus( this ); 0191 } 0192 0193 void 0194 Token::updateCursor() 0195 { 0196 if( isEnabled() ) 0197 setCursor( Qt::OpenHandCursor ); 0198 else 0199 unsetCursor(); 0200 } 0201 0202 void 0203 Token::mousePressEvent( QMouseEvent* event ) 0204 { 0205 if( event->button() == Qt::LeftButton ) 0206 m_startPos = event->pos(); //store the start position 0207 QWidget::mousePressEvent( event ); //feed it to parent's event 0208 } 0209 0210 void 0211 Token::mouseMoveEvent( QMouseEvent* event ) 0212 { 0213 if( isEnabled() && 0214 event->buttons() & Qt::LeftButton ) 0215 { 0216 int distance = ( event->pos() - m_startPos ).manhattanLength(); 0217 if ( distance >= QApplication::startDragDistance() ) 0218 performDrag(); 0219 } 0220 QWidget::mouseMoveEvent( event ); 0221 } 0222 0223 //Handles the creation of a QDrag object that carries the (text-only) QDataStream from an item in TokenPool 0224 void 0225 Token::performDrag() 0226 { 0227 bool stacked = parentWidget() && qobject_cast<TokenDropTarget*>( parentWidget() ); // true if token originated from a TokenDropTarget. 0228 if( stacked ) 0229 hide(); 0230 0231 QDrag *drag = new QDrag( this ); 0232 drag->setMimeData( mimeData() ); 0233 0234 // icon for pointer 0235 QPixmap pixmap( size() ); 0236 render( &pixmap ); 0237 drag->setPixmap( pixmap ); 0238 drag->setHotSpot ( pixmap.rect().center() ); 0239 0240 Qt::DropAction dropAction = drag->exec( Qt::MoveAction | Qt::CopyAction, Qt::CopyAction ); 0241 0242 if( dropAction != Qt::MoveAction && dropAction != Qt::CopyAction ) // dragged out and not just dragged to another position. 0243 { 0244 // TODO: nice poof animation? ;-) 0245 Q_EMIT removed( this ); 0246 deleteLater(); 0247 } 0248 0249 } 0250 0251 void Token::paintEvent(QPaintEvent *pe) 0252 { 0253 Q_UNUSED( pe ) 0254 0255 QPainter p( this ); 0256 p.setBrush( Qt::NoBrush ); 0257 p.setRenderHint( QPainter::Antialiasing ); 0258 QColor c; 0259 if( isEnabled() && hasFocus() ) 0260 { 0261 c = palette().color( QPalette::Highlight ); 0262 } 0263 else if( isEnabled() ) 0264 { 0265 c = palette().color( foregroundRole() ); 0266 c.setAlpha( c.alpha() * 0.5 ); 0267 } 0268 else 0269 { 0270 c = palette().color( foregroundRole() ); 0271 c.setAlpha( c.alpha() * 0.3 ); 0272 } 0273 p.setPen( QPen( c, 2 ) ); 0274 p.drawRoundedRect( rect().adjusted(1,1,-1,-1), 4, 4 ); 0275 p.end(); 0276 } 0277 0278