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