File indexing completed on 2024-05-05 04:49:30

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>                                *
0003  * Copyright (c) 2009 Roman Jarosz <kedgedev@gmail.com>                                 *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #include "TokenWithLayout.h"
0019 
0020 #include "core/support/Debug.h"
0021 #include "TokenDropTarget.h"
0022 #include "playlist/layouts/LayoutEditDialog.h"
0023 
0024 #include <KColorScheme>
0025 #include <QIcon>
0026 #include <KLocalizedString>
0027 
0028 #include <QContextMenuEvent>
0029 #include <QLayout>
0030 #include <QPainter>
0031 #include <QPushButton>
0032 #include <QTimerEvent>
0033 
0034 Wrench::Wrench( QWidget *parent ) : QLabel( parent )
0035 {
0036     setCursor( Qt::ArrowCursor );
0037     setPixmap( QIcon::fromTheme( QStringLiteral("configure") ).pixmap( 64 ) );
0038     setScaledContents( true );
0039     setMargin( 4 );
0040 }
0041 
0042 void Wrench::enterEvent( QEvent * )
0043 {
0044     setMargin( 1 );
0045     update();
0046 }
0047 
0048 void Wrench::leaveEvent( QEvent * )
0049 {
0050     setMargin( 4 );
0051     update();
0052 }
0053 
0054 void Wrench::mousePressEvent( QMouseEvent * )
0055 {
0056     setMargin( 4 );
0057     update();
0058     Q_EMIT clicked();
0059 }
0060 
0061 void Wrench::mouseReleaseEvent( QMouseEvent * )
0062 {
0063     setMargin( 1 );
0064     update();
0065     Q_EMIT clicked();
0066 }
0067 
0068 void Wrench::paintEvent( QPaintEvent *pe )
0069 {
0070     QPainter p( this );
0071     QColor c = palette().color( backgroundRole() );
0072     p.setPen( Qt::NoPen );
0073     c = palette().color( backgroundRole() );
0074     c.setAlpha( 212 );
0075     p.setBrush( c );
0076     p.setRenderHint( QPainter::Antialiasing );
0077     p.drawEllipse( rect() );
0078     p.end();
0079     QLabel::paintEvent( pe );
0080 }
0081 
0082 
0083 const QString ActionBoldName = QLatin1String( "ActionBold" );
0084 const QString ActionItalicName = QLatin1String( "ActionItalic" );
0085 const QString ActionAlignLeftName = QLatin1String( "ActionAlignLeft" );
0086 const QString ActionAlignCenterName = QLatin1String( "ActionAlignCenter" );
0087 const QString ActionAlignRightName = QLatin1String( "ActionAlignRight" );
0088 
0089 Token * TokenWithLayoutFactory::createToken( const QString &text, const QString &iconName, qint64 value, QWidget *parent ) const
0090 {
0091     return new TokenWithLayout( text, iconName, value, parent );
0092 }
0093 
0094 QPointer<LayoutEditDialog> TokenWithLayout::m_dialog;
0095 
0096 TokenWithLayout::TokenWithLayout( const QString &text, const QString &iconName, qint64 value, QWidget *parent )
0097     : Token( text, iconName, value, parent  )
0098     , m_width( 0.0 ), m_wrenchTimer( 0 )
0099 {
0100     m_alignment = Qt::AlignCenter;
0101     m_bold = false;
0102     m_italic = false;
0103     m_underline = false;
0104     m_wrench = new Wrench( this );
0105     m_wrench->installEventFilter( this );
0106     m_wrench->hide();
0107     connect ( m_wrench, &Wrench::clicked, this, &TokenWithLayout::showConfig );
0108     setFocusPolicy( Qt::ClickFocus );
0109 }
0110 
0111 
0112 TokenWithLayout::~TokenWithLayout()
0113 {
0114     delete m_wrench;
0115 }
0116 
0117 void TokenWithLayout::enterEvent( QEvent *e )
0118 {
0119     QWidget *win = window();
0120     const int sz = 2*height();
0121     QPoint pt = mapTo( win, rect().topLeft() );
0122 
0123     m_wrench->setParent( win );
0124     m_wrench->setFixedSize( sz, sz );
0125     m_wrench->move( pt - QPoint( m_wrench->width()/3, m_wrench->height()/3 ) );
0126     m_wrench->setCursor( Qt::PointingHandCursor );
0127     m_wrench->raise();
0128     m_wrench->show();
0129 
0130     Token::enterEvent( e );
0131 }
0132 
0133 bool TokenWithLayout::eventFilter( QObject *o, QEvent *e )
0134 {
0135     if ( e->type() == QEvent::Leave && o == m_wrench )
0136     {
0137         if ( m_wrenchTimer )
0138             killTimer( m_wrenchTimer );
0139         m_wrenchTimer = startTimer( 40 );
0140     }
0141     return false;
0142 }
0143 
0144 void TokenWithLayout::leaveEvent( QEvent *e )
0145 {
0146     Token::leaveEvent( e );
0147     if ( m_wrenchTimer )
0148         killTimer( m_wrenchTimer );
0149     m_wrenchTimer = startTimer( 40 );
0150 }
0151 
0152 void TokenWithLayout::showConfig()
0153 {
0154     if( !m_dialog )
0155         m_dialog = new LayoutEditDialog( window() );
0156     m_dialog->setToken( this );
0157     if( !m_dialog->isVisible() )
0158     {
0159         m_dialog->adjustSize();
0160         QPoint pt = mapToGlobal( rect().bottomLeft() );
0161         pt.setY( pt.y() + 9 );
0162         if ( parentWidget() )
0163             pt.setX( parentWidget()->mapToGlobal( QPoint( 0, 0 ) ).x() + ( parentWidget()->width() - m_dialog->QDialog::width() ) / 2 );
0164         m_dialog->move( pt );
0165     }
0166     m_dialog->show(); // ensures raise in doubt
0167     QTimerEvent te( m_wrenchTimer );
0168     timerEvent( &te ); // it's not like we'd get a leave event when the child dialog pops in between...
0169 }
0170 
0171 void TokenWithLayout::timerEvent( QTimerEvent *te )
0172 {
0173     if ( te->timerId() == m_wrenchTimer )
0174     {
0175         killTimer( m_wrenchTimer );
0176         m_wrenchTimer = 0;
0177 
0178         QRegion rgn;
0179         rgn |= QRect( mapToGlobal( QPoint( 0, 0 ) ), QWidget::size() );
0180         rgn |= QRect( m_wrench->mapToGlobal( QPoint( 0, 0 ) ), m_wrench->size() );
0181         if ( !rgn.contains( QCursor::pos() ) )
0182             m_wrench->hide();
0183     }
0184     Token::timerEvent( te );
0185 }
0186 
0187 Qt::Alignment TokenWithLayout::alignment()
0188 {
0189     return m_alignment;
0190 }
0191 
0192 void TokenWithLayout::setAlignment( Qt::Alignment alignment )
0193 {
0194     if ( m_alignment == alignment )
0195         return;
0196 
0197     m_alignment = alignment;
0198     m_label->setAlignment( alignment );
0199     Q_EMIT changed();
0200 }
0201 
0202 bool TokenWithLayout::bold() const
0203 {
0204     return m_bold;
0205 }
0206 
0207 void TokenWithLayout::setBold( bool bold )
0208 {
0209     if ( m_bold == bold )
0210         return;
0211 
0212     m_bold = bold;
0213     QFont font = m_label->font();
0214     font.setBold( bold );
0215     m_label->setFont( font );
0216     Q_EMIT changed();
0217 }
0218 
0219 void TokenWithLayout::setPrefix( const QString& string )
0220 {
0221     if ( m_prefix == string )
0222         return;
0223     if ( string == i18n( "[prefix]" ) )
0224         m_prefix.clear();
0225     else
0226         m_prefix = string;
0227     Q_EMIT changed();
0228 }
0229 
0230 void TokenWithLayout::setSuffix( const QString& string )
0231 {
0232     if ( m_suffix == string )
0233         return;
0234     if ( string == i18n( "[suffix]" ) )
0235         m_suffix.clear();
0236     else
0237         m_suffix = string;
0238     Q_EMIT changed();
0239 }
0240 
0241 void TokenWithLayout::setWidth( int size )
0242 {
0243     m_width = qMax( qMin( 1.0, size/100.0 ), 0.0 ) ;
0244 
0245     Q_EMIT changed();
0246 }
0247 
0248 qreal TokenWithLayout::width() const
0249 {
0250     return m_width;
0251 }
0252 
0253 bool TokenWithLayout::italic() const
0254 {
0255     return m_italic;
0256 }
0257 
0258 bool TokenWithLayout::underline() const
0259 {
0260     return m_underline;
0261 }
0262 
0263 void TokenWithLayout::setItalic( bool italic )
0264 {
0265     if ( m_italic == italic )
0266         return;
0267 
0268     m_italic = italic;
0269     QFont font = m_label->font();
0270     font.setItalic( italic );
0271     m_label->setFont( font );
0272 
0273     Q_EMIT changed();
0274 }
0275 
0276 void TokenWithLayout::setUnderline( bool underline )
0277 {
0278     if( m_underline == underline )
0279         return;
0280 
0281     m_underline = underline;
0282     QFont font  = m_label->font();
0283     font.setUnderline( underline );
0284     m_label->setFont( font );
0285 
0286     Q_EMIT changed();
0287 }
0288 
0289 
0290 
0291 
0292