KDEUI
ksqueezedtextlabel.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Ronny Standtke <Ronny.Standtke@gmx.de> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "ksqueezedtextlabel.h" 00020 #include <kdebug.h> 00021 #include <klocale.h> 00022 #include <QContextMenuEvent> 00023 #include <kaction.h> 00024 #include <QMenu> 00025 #include <QClipboard> 00026 #include <QApplication> 00027 #include <QMimeData> 00028 #include <kglobalsettings.h> 00029 00030 class KSqueezedTextLabelPrivate 00031 { 00032 public: 00033 00034 void _k_copyFullText() { 00035 QApplication::clipboard()->setText(fullText); 00036 } 00037 00038 QString fullText; 00039 Qt::TextElideMode elideMode; 00040 }; 00041 00042 KSqueezedTextLabel::KSqueezedTextLabel(const QString &text , QWidget *parent) 00043 : QLabel (parent), 00044 d(new KSqueezedTextLabelPrivate) 00045 { 00046 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); 00047 d->fullText = text; 00048 d->elideMode = Qt::ElideMiddle; 00049 squeezeTextToLabel(); 00050 } 00051 00052 KSqueezedTextLabel::KSqueezedTextLabel(QWidget *parent) 00053 : QLabel (parent), 00054 d(new KSqueezedTextLabelPrivate) 00055 { 00056 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); 00057 d->elideMode = Qt::ElideMiddle; 00058 } 00059 00060 KSqueezedTextLabel::~KSqueezedTextLabel() 00061 { 00062 delete d; 00063 } 00064 00065 void KSqueezedTextLabel::resizeEvent(QResizeEvent *) 00066 { 00067 squeezeTextToLabel(); 00068 } 00069 00070 QSize KSqueezedTextLabel::minimumSizeHint() const 00071 { 00072 QSize sh = QLabel::minimumSizeHint(); 00073 sh.setWidth(-1); 00074 return sh; 00075 } 00076 00077 QSize KSqueezedTextLabel::sizeHint() const 00078 { 00079 int maxWidth = KGlobalSettings::desktopGeometry(this).width() * 3 / 4; 00080 QFontMetrics fm(fontMetrics()); 00081 int textWidth = fm.width(d->fullText); 00082 if (textWidth > maxWidth) { 00083 textWidth = maxWidth; 00084 } 00085 return QSize(textWidth, QLabel::sizeHint().height()); 00086 } 00087 00088 void KSqueezedTextLabel::setText(const QString &text) 00089 { 00090 d->fullText = text; 00091 squeezeTextToLabel(); 00092 } 00093 00094 void KSqueezedTextLabel::clear() 00095 { 00096 d->fullText.clear(); 00097 QLabel::clear(); 00098 } 00099 00100 void KSqueezedTextLabel::squeezeTextToLabel() 00101 { 00102 QFontMetrics fm(fontMetrics()); 00103 int labelWidth = size().width(); 00104 QStringList squeezedLines; 00105 bool squeezed = false; 00106 Q_FOREACH(const QString& line, d->fullText.split('\n')) { 00107 int lineWidth = fm.width(line); 00108 if (lineWidth > labelWidth) { 00109 squeezed = true; 00110 squeezedLines << fm.elidedText(line, d->elideMode, labelWidth); 00111 } else { 00112 squeezedLines << line; 00113 } 00114 } 00115 00116 if (squeezed) { 00117 QLabel::setText(squeezedLines.join("\n")); 00118 setToolTip(d->fullText); 00119 } else { 00120 QLabel::setText(d->fullText); 00121 setToolTip(QString()); 00122 } 00123 } 00124 00125 void KSqueezedTextLabel::setAlignment(Qt::Alignment alignment) 00126 { 00127 // save fullText and restore it 00128 QString tmpFull(d->fullText); 00129 QLabel::setAlignment(alignment); 00130 d->fullText = tmpFull; 00131 } 00132 00133 Qt::TextElideMode KSqueezedTextLabel::textElideMode() const 00134 { 00135 return d->elideMode; 00136 } 00137 00138 void KSqueezedTextLabel::setTextElideMode(Qt::TextElideMode mode) 00139 { 00140 d->elideMode = mode; 00141 squeezeTextToLabel(); 00142 } 00143 00144 QString KSqueezedTextLabel::fullText() const 00145 { 00146 return d->fullText; 00147 } 00148 00149 void KSqueezedTextLabel::contextMenuEvent(QContextMenuEvent* ev) 00150 { 00151 // We want to reimplement "Copy" to include the elided text. 00152 // But this means reimplementing the full popup menu, so no more 00153 // copy-link-address or copy-selection support anymore, since we 00154 // have no access to the QTextDocument. 00155 // Maybe we should have a boolean flag in KSqueezedTextLabel itself for 00156 // whether to show the "Copy Full Text" custom popup? 00157 // For now I chose to show it when the text is squeezed; when it's not, the 00158 // standard popup menu can do the job (select all, copy). 00159 00160 const bool squeezed = text() != d->fullText; 00161 const bool showCustomPopup = squeezed; 00162 if (showCustomPopup) { 00163 QMenu menu(this); 00164 00165 KAction* act = new KAction(i18n("&Copy Full Text"), this); 00166 connect(act, SIGNAL(triggered()), this, SLOT(_k_copyFullText())); 00167 menu.addAction(act); 00168 00169 ev->accept(); 00170 menu.exec(ev->globalPos()); 00171 } else { 00172 QLabel::contextMenuEvent(ev); 00173 } 00174 } 00175 00176 void KSqueezedTextLabel::mouseReleaseEvent(QMouseEvent* ev) 00177 { 00178 #if QT_VERSION >= 0x040700 00179 if (QApplication::clipboard()->supportsSelection() && 00180 textInteractionFlags() != Qt::NoTextInteraction && 00181 ev->button() == Qt::LeftButton && 00182 !d->fullText.isEmpty() && 00183 hasSelectedText()) { 00184 // Expand "..." when selecting with the mouse 00185 QString txt = selectedText(); 00186 const QChar ellipsisChar(0x2026); // from qtextengine.cpp 00187 const int dotsPos = txt.indexOf(ellipsisChar); 00188 if (dotsPos > -1) { 00189 // Ex: abcde...yz, selecting de...y (selectionStart=3) 00190 // charsBeforeSelection = selectionStart = 2 (ab) 00191 // charsAfterSelection = 1 (z) 00192 // final selection length= 26 - 2 - 1 = 23 00193 const int start = selectionStart(); 00194 const int charsAfterSelection = text().length() - start - selectedText().length(); 00195 txt = d->fullText.mid(selectionStart(), d->fullText.length() - start - charsAfterSelection); 00196 } 00197 QApplication::clipboard()->setText(txt, QClipboard::Selection); 00198 } else 00199 #endif 00200 { 00201 QLabel::mouseReleaseEvent(ev); 00202 } 00203 } 00204 00205 #include "ksqueezedtextlabel.moc"
KDE 4.6 API Reference