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

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Casey Link <unnamedrambler@gmail.com>                             *
0003  * Copyright (c) 2009 Simon Bühler <simon@aktionspotenzial.de>                          *
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 "BookmarkPopup.h"
0019 
0020 #include "SvgHandler.h"
0021 #include "amarokurls/BookmarkModel.h"
0022 #include "core/support/Debug.h"
0023 #include "widgets/BookmarkTriangle.h"
0024 
0025 #include <KLocalizedString>
0026 
0027 #include <QPainter>
0028 #include <QHBoxLayout>
0029 
0030 BookmarkPopup::BookmarkPopup (QWidget* parent, const QString &label, BookmarkTriangle* triangle )
0031         : QWidget ( parent )
0032         , m_label ( label )
0033         , m_triangle ( triangle )
0034 
0035 {
0036     m_timer = new QTimer ( this );
0037     connect ( m_timer, &QTimer::timeout, this, &BookmarkPopup::hideTimerAction );
0038 
0039     m_displayNeeded = true;
0040     m_hasMouseOver = false;
0041     m_overDelete = false;
0042     m_isEditMode = false;
0043 
0044     m_deleteIcon = QIcon::fromTheme( "edit-delete" );
0045     adjustWidth();
0046 
0047     m_edit = new QLineEdit ( m_label, nullptr );
0048     m_edit->setVisible ( false );
0049     m_edit->setAlignment ( Qt::AlignHCenter );
0050     connect ( m_edit, &QLineEdit::returnPressed, this, &BookmarkPopup::editValueChanged );
0051     
0052     QVBoxLayout * layout = new QVBoxLayout;
0053     layout->setContentsMargins ( 1, 0, 0, 0 );
0054     layout->addSpacing ( m_lineHeight + 2 );
0055     layout->addWidget ( m_edit );
0056     setLayout ( layout );
0057     setMouseTracking ( true );
0058     setFocusPolicy(Qt::StrongFocus);
0059 }
0060 
0061 QSize BookmarkPopup::sizeHint() const
0062 {
0063     return QSize ( m_width, m_height );
0064 }
0065 
0066 QSizePolicy BookmarkPopup::sizePolicy() const
0067 {
0068     return QSizePolicy ( QSizePolicy::Preferred, QSizePolicy::Minimum );
0069 }
0070 
0071 QSize BookmarkPopup::minimumSizeHint() const
0072 {
0073     return QSize ( m_width, m_height );
0074 }
0075 
0076 void BookmarkPopup::adjustWidth()
0077 {
0078     //calculate height and width
0079     const int margin = 3;
0080     QFontMetrics fm ( font() );
0081     m_lineHeight = fm.height();
0082     int line1Width = fm.horizontalAdvance ( i18n ( "Bookmark" ) ) + 40; //padding and space for delete icon
0083     int line2Width = fm.horizontalAdvance ( m_label ) + 8 ;
0084     m_height = 44;
0085     m_width = qMax ( line1Width, line2Width ) + 2 * margin;
0086     resize ( m_width, m_height );
0087     m_deleteIconRect = QRect ( m_width - 20, 4, 16, 16 );
0088 }
0089 
0090 void BookmarkPopup::paintEvent ( QPaintEvent* event )
0091 {
0092     QPainter p ( this );
0093     p.setRenderHint ( QPainter::Antialiasing );
0094     p.setBrush ( Qt::white );
0095     p.setOpacity ( 0.85 );
0096     QPen pen = QPen ( Qt::black );
0097     pen.setCosmetic ( true );
0098     p.setPen ( pen );
0099     QRect rect = QRect ( 0,0, m_width, m_height );
0100     p.drawRoundedRect ( rect, 5, 5 );
0101 
0102     if ( m_overDelete ) p.setOpacity ( m_overDelete ?  1 : 0.1 );
0103     p.drawPixmap ( m_deleteIconRect.x(), m_deleteIconRect.y(), m_deleteIcon.pixmap ( 16 ) );
0104 
0105     p.setOpacity ( 1 );
0106     p.drawPixmap ( 5, 1, The::svgHandler()->renderSvg ( "bookmarks", 6, 20, "bookmarks" ) );
0107 
0108     p.setPen ( Qt::gray );
0109     rect = QRect ( 15, 3, m_width, m_lineHeight );
0110     p.drawText ( rect, Qt::AlignLeft, i18n ( "Bookmark" ) );
0111 
0112     if ( m_isEditMode ) // paint Label or render QLineEdit
0113     {
0114         event->accept();
0115     }
0116     else
0117     {
0118         p.setPen ( Qt::black );
0119         rect = QRect ( 0, m_lineHeight + 8, m_width, m_lineHeight );
0120         p.drawText ( rect, Qt::AlignCenter, m_label );
0121     }
0122 
0123 }
0124 
0125 void BookmarkPopup::mouseReleaseEvent ( QMouseEvent * event )
0126 {
0127     if ( event->button() == Qt::LeftButton )
0128     {
0129         if ( isOverDeleteIcon ( event->pos() ) ) // handle close
0130         {
0131             m_triangle->deleteBookmark();
0132             return;
0133         }
0134         if ( isOverTitleLabel ( event->pos() ) ) // handle click in editable Area
0135         {
0136             if ( m_isEditMode )
0137                 return;
0138             
0139             m_isEditMode = true; // switch to Editmode
0140             m_edit->setVisible ( m_isEditMode );
0141             m_edit->setFocus();
0142             update();
0143             return;
0144         }
0145         // other clicks discard changes and leave Editmode
0146         m_isEditMode = false;
0147         m_edit->setVisible ( m_isEditMode );
0148         m_edit->setText( m_label );
0149         update();
0150     }
0151 }
0152 
0153 void BookmarkPopup::mouseMoveEvent ( QMouseEvent * event )
0154 {
0155     // Monitor for DeleteIcon highlighting
0156     bool state = isOverDeleteIcon ( event->pos() );
0157     if ( state != m_overDelete )
0158     {
0159         m_overDelete = state;
0160         this->update();
0161     }
0162 }
0163 
0164 void BookmarkPopup::enterEvent ( QEvent* )
0165 {
0166     m_hasMouseOver = true;
0167 }
0168 
0169 void BookmarkPopup::leaveEvent ( QEvent* )
0170 {
0171     m_hasMouseOver = false;
0172     startHideTimer();
0173 
0174 }
0175 
0176 void BookmarkPopup::displayNeeded ( bool value )
0177 {
0178     m_displayNeeded  = value;
0179     if ( !m_displayNeeded ) startHideTimer();
0180 }
0181 
0182 void BookmarkPopup::hideTimerAction ( )
0183 {
0184     if ( m_hasMouseOver ||  m_isEditMode  || m_displayNeeded )
0185         return;
0186 
0187     m_timer->stop();
0188     hide();
0189 }
0190 
0191 void BookmarkPopup::editValueChanged()
0192 {
0193     if ( m_label != m_edit->text() && m_edit->text().trimmed().length() > 0 )
0194     {
0195         BookmarkModel::instance()->renameBookmark( m_label, m_edit->text().trimmed() );
0196         return;
0197     }
0198     m_isEditMode = false;
0199     m_edit->setVisible ( m_isEditMode );
0200     update();
0201 }
0202 
0203 void BookmarkPopup::startHideTimer()
0204 {
0205     m_timer->start ( 500 );
0206 }
0207 
0208 bool BookmarkPopup::isOverDeleteIcon ( QPoint pos )
0209 {
0210     return m_deleteIconRect.contains ( pos );
0211 }
0212 
0213 
0214 bool BookmarkPopup::isOverTitleLabel ( QPoint pos )
0215 {
0216     return ( pos.y() > m_lineHeight +2 );
0217 }