1 /****************************************************************************************
2  * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>                                *
3  * Copyright (c) 2009 Seb Ruiz <ruiz@kde.org>                                           *
4  *                                                                                      *
5  * This program is free software; you can redistribute it and/or modify it under        *
6  * the terms of the GNU General Public License as published by the Free Software        *
7  * Foundation; either version 2 of the License, or (at your option) any later           *
8  * version.                                                                             *
9  *                                                                                      *
10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13  *                                                                                      *
14  * You should have received a copy of the GNU General Public License along with         *
15  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16  ****************************************************************************************/
17 
18 #include "ElidingButton.h"
19 
20 #include "core/support/Debug.h"
21 
22 #include <QFontMetrics>
23 
24 namespace Amarok {
25 
ElidingButton(QWidget * parent)26 ElidingButton::ElidingButton( QWidget *parent )
27     : QPushButton( parent )
28 {
29     init();
30 }
31 
ElidingButton(const QString & text,QWidget * parent)32 ElidingButton::ElidingButton( const QString & text, QWidget * parent )
33     : QPushButton( text, parent )
34     , m_fullText( text )
35 {
36     init();
37 }
38 
ElidingButton(const QIcon & icon,const QString & text,QWidget * parent)39 ElidingButton::ElidingButton( const QIcon & icon, const QString & text, QWidget * parent )
40     : QPushButton( icon, text, parent )
41     , m_fullText( text )
42 {
43     init();
44 }
45 
~ElidingButton()46 ElidingButton::~ElidingButton()
47 {
48 }
49 
init()50 void ElidingButton::init()
51 {
52     m_isElided = false;
53     int width = iconSize().width() + 4;
54     if( !text().isEmpty() )
55     {
56         QFontMetrics fm( font() );
57         width += fm.width( QLatin1String( "XX" ) ) / 2;
58     }
59     setMinimumWidth( width );
60 }
61 
sizePolicy() const62 QSizePolicy ElidingButton::sizePolicy() const
63 {
64     //This has got to be the mother of all hacks...
65     //If the text is currently elided, the button should try to get more space. If not elided
66     //then the button has all the space it needs and should really not try to expand beyond this.
67     //Since the size hint depends on the actual text shown (which is very short when elided) we
68     //cannot depend on this for making the button grow again...
69     if( !m_isElided )
70         return QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed );
71 
72     return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
73 }
74 
isElided() const75 bool ElidingButton::isElided() const
76 {
77     return m_isElided;
78 }
79 
resizeEvent(QResizeEvent * event)80 void ElidingButton::resizeEvent( QResizeEvent *event )
81 {
82     elideText( event->size() );
83     QPushButton::resizeEvent( event );
84 }
85 
setText(const QString & text)86 void ElidingButton::setText( const QString &text )
87 {
88     m_fullText = text;
89     elideText( size() );
90     // elideText will call QPushButton::setText()
91 }
92 
elideText(const QSize & widgetSize)93 void ElidingButton::elideText( const QSize &widgetSize )
94 {
95     const int width = widgetSize.width();
96     const int iconWidth = icon().isNull() ? 0 : iconSize().width();
97 
98     int left, top, right, bottom;
99     getContentsMargins( &left, &top, &right, &bottom );
100     int padding = left + right + 4;
101     int textWidth = width - ( iconWidth + padding );
102 
103     QFontMetrics fm( font() );
104     QString elidedText = fm.elidedText( m_fullText, Qt::ElideRight, textWidth );
105     QPushButton::setText( elidedText );
106 
107     bool elided = ( elidedText != m_fullText );
108 
109     // If there is no tooltip set, then we set it to be the full text when elided,
110     // and clear it if the button is no longer elided.
111     const QString tip = toolTip();
112     if( elided && tip.isEmpty() )
113         setToolTip( m_fullText );
114     else if( !elided && tip == m_fullText )
115         setToolTip( QString() );
116 
117     if( elided )
118         setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
119     else
120         setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed );
121 
122     if( m_isElided != elided )
123     {
124         m_isElided = elided;
125         Q_EMIT( sizePolicyChanged() );
126     }
127 }
128 
129 }
130 
131