# HG changeset patch # User Chris Cannam # Date 1321372938 0 # Node ID d869e6a18f631d7a6b09f608fc8ab011eefabc29 # Parent 43ddfa5e9fd017a013f4c4b3c5ad4a62eb1ad1b0 Make the text labels in the work status area squeezable for small window sizes. Fixes #329 diff -r 43ddfa5e9fd0 -r d869e6a18f63 easyhg.pro --- a/easyhg.pro Tue Nov 15 14:47:19 2011 +0000 +++ b/easyhg.pro Tue Nov 15 16:02:18 2011 +0000 @@ -63,7 +63,8 @@ src/moreinformationdialog.h \ src/annotatedialog.h \ src/hgignoredialog.h \ - src/versiontester.h + src/versiontester.h \ + src/squeezedlabel.h SOURCES = \ src/main.cpp \ src/mainwindow.cpp \ @@ -99,7 +100,8 @@ src/moreinformationdialog.cpp \ src/annotatedialog.cpp \ src/hgignoredialog.cpp \ - src/versiontester.cpp + src/versiontester.cpp \ + src/squeezedlabel.cpp macx-* { SOURCES += src/common_osx.mm diff -r 43ddfa5e9fd0 -r d869e6a18f63 src/clickablelabel.h --- a/src/clickablelabel.h Tue Nov 15 14:47:19 2011 +0000 +++ b/src/clickablelabel.h Tue Nov 15 16:02:18 2011 +0000 @@ -18,9 +18,11 @@ #ifndef _CLICKABLE_LABEL_H_ #define _CLICKABLE_LABEL_H_ -#include +#include "squeezedlabel.h" -class ClickableLabel : public QLabel +#include + +class ClickableLabel : public SqueezedLabel { Q_OBJECT @@ -28,12 +30,12 @@ public: ClickableLabel(const QString &text, QWidget *parent = 0) : - QLabel(text, parent), + SqueezedLabel(text, parent), m_naturalText(text) { } ClickableLabel(QWidget *parent = 0) : - QLabel(parent) + SqueezedLabel(parent) { } ~ClickableLabel() @@ -41,7 +43,7 @@ void setText(const QString &t) { m_naturalText = t; - QLabel::setText(t); + SqueezedLabel::setText(t); } bool mouseUnderline() const { @@ -62,18 +64,22 @@ protected: virtual void enterEvent(QEvent *) { if (m_mouseUnderline) { - QLabel::setText(tr("%1").arg(m_naturalText)); + SqueezedLabel::setText(tr("%1").arg(m_naturalText)); } } virtual void leaveEvent(QEvent *) { if (m_mouseUnderline) { - QLabel::setText(m_naturalText); + SqueezedLabel::setText(m_naturalText); } } - virtual void mousePressEvent(QMouseEvent *) { - emit clicked(); + virtual void mousePressEvent(QMouseEvent *ev) { + if (ev->button() == Qt::LeftButton) { + emit clicked(); + } else { + SqueezedLabel::mousePressEvent(ev); + } } private: diff -r 43ddfa5e9fd0 -r d869e6a18f63 src/squeezedlabel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/squeezedlabel.cpp Tue Nov 15 16:02:18 2011 +0000 @@ -0,0 +1,180 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on HgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +/* + This file adapted from Rosegarden, a sequencer and musical + notation editor. Copyright 2000-2011 the Rosegarden development + team. + + Adapted from KDE 4.2.0, this code originally Copyright (c) 2000 + Ronny Standtke. +*/ + +#include "squeezedlabel.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + + +class SqueezedLabelPrivate +{ +public: +}; + +void SqueezedLabel::_k_copyFullText() +{ + QMimeData* data = new QMimeData; + data->setText(fullText); + QApplication::clipboard()->setMimeData(data); +} + +SqueezedLabel::SqueezedLabel(const QString &text , QWidget *parent) + : QLabel (parent) +{ + setObjectName("SQUEEZED"); + setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + fullText = text; + elideMode = Qt::ElideMiddle; + squeezeTextToLabel(); +} + +SqueezedLabel::SqueezedLabel(QWidget *parent) + : QLabel (parent) +{ + setObjectName("SQUEEZED"); + setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + elideMode = Qt::ElideMiddle; +} + +SqueezedLabel::~SqueezedLabel() +{ +} + +void SqueezedLabel::resizeEvent(QResizeEvent *) +{ + squeezeTextToLabel(); +} + +QSize SqueezedLabel::minimumSizeHint() const +{ + QSize sh = QLabel::minimumSizeHint(); + sh.setWidth(-1); + return sh; +} + +QSize SqueezedLabel::sizeHint() const +{ + int dw = QApplication::desktop()->availableGeometry(QPoint(0, 0)).width(); + int maxWidth = dw * 3 / 4; + QFontMetrics fm(fontMetrics()); + int textWidth = fm.width(fullText); + if (textWidth > maxWidth) { + textWidth = maxWidth; + } + return QSize(textWidth, QLabel::sizeHint().height()); +} + +void SqueezedLabel::setText(const QString &text) +{ + fullText = text; + squeezeTextToLabel(); +} + +void SqueezedLabel::clear() { + fullText.clear(); + QLabel::clear(); +} + +void SqueezedLabel::squeezeTextToLabel() { + QFontMetrics fm(fontMetrics()); + int labelWidth = size().width(); + QStringList squeezedLines; + bool squeezed = false; + Q_FOREACH(const QString& line, fullText.split('\n')) { + int lineWidth = fm.width(line); + if (lineWidth > labelWidth) { + squeezed = true; + squeezedLines << fm.elidedText(line, elideMode, labelWidth); + } else { + squeezedLines << line; + } + } + + if (squeezed) { + QLabel::setText(squeezedLines.join("\n")); + setToolTip(fullText); + } else { + QLabel::setText(fullText); + setToolTip(QString()); + } +} + +void SqueezedLabel::setAlignment(Qt::Alignment alignment) +{ + // save fullText and restore it + QString tmpFull(fullText); + QLabel::setAlignment(alignment); + fullText = tmpFull; +} + +Qt::TextElideMode SqueezedLabel::textElideMode() const +{ + return elideMode; +} + +void SqueezedLabel::setTextElideMode(Qt::TextElideMode mode) +{ + elideMode = mode; + squeezeTextToLabel(); +} + +void SqueezedLabel::contextMenuEvent(QContextMenuEvent* ev) +{ + // "We" means the KDE team here. + // + // We want to reimplement "Copy" to include the elided text. + // But this means reimplementing the full popup menu, so no more + // copy-link-address or copy-selection support anymore, since we + // have no access to the QTextDocument. + // Maybe we should have a boolean flag in SqueezedLabel itself for + // whether to show the "Copy Full Text" custom popup? + // For now I chose to show it when the text is squeezed; when it's not, the + // standard popup menu can do the job (select all, copy). + + const bool squeezed = text() != fullText; + const bool showCustomPopup = squeezed; + if (showCustomPopup) { + QMenu menu(this); + + QAction* act = new QAction(tr("&Copy Full Text"), this); + connect(act, SIGNAL(triggered()), this, SLOT(_k_copyFullText())); + menu.addAction(act); + + ev->accept(); + menu.exec(ev->globalPos()); + } else { + QLabel::contextMenuEvent(ev); + } +} + diff -r 43ddfa5e9fd0 -r d869e6a18f63 src/squeezedlabel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/squeezedlabel.h Tue Nov 15 16:02:18 2011 +0000 @@ -0,0 +1,120 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on HgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +/* + This file adapted from Rosegarden, a sequencer and musical + notation editor. Copyright 2000-2011 the Rosegarden development + team. + + Adapted from KDE 4.2.0, this code originally Copyright (c) 2000 + Ronny Standtke. +*/ + +#ifndef _SQUEEZED_LABEL_H_ +#define _SQUEEZED_LABEL_H_ + +#include + +class SqueezedLabelPrivate; + +/** + * @short A replacement for QLabel that squeezes its text + * + * A label class that squeezes its text into the label + * + * If the text is too long to fit into the label it is divided into + * remaining left and right parts which are separated by three dots. + */ + +class SqueezedLabel : public QLabel +{ + Q_OBJECT + Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode) + +public: + /** + * Default constructor. + */ + explicit SqueezedLabel(QWidget *parent = 0); + explicit SqueezedLabel(const QString &text, QWidget *parent = 0); + + virtual ~SqueezedLabel(); + + virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const; + /** + * Overridden for internal reasons; the API remains unaffected. + */ + virtual void setAlignment(Qt::Alignment); + + /** + * Returns the text elide mode. + */ + Qt::TextElideMode textElideMode() const; + + /** + * Sets the text elide mode. + * @param mode The text elide mode. + */ + void setTextElideMode(Qt::TextElideMode mode); + +public Q_SLOTS: + /** + * Sets the text. Note that this is not technically a reimplementation of QLabel::setText(), + * which is not virtual (in Qt 4.3). Therefore, you may need to cast the object to + * SqueezedLabel in some situations: + * \Example + * \code + * SqueezedLabel* squeezed = new SqueezedLabel("text", parent); + * QLabel* label = squeezed; + * label->setText("new text"); // this will not work + * squeezed->setText("new text"); // works as expected + * static_cast(label)->setText("new text"); // works as expected + * \endcode + * @param mode The new text. + */ + void setText(const QString &text); + /** + * Clears the text. Same remark as above. + * + */ + void clear(); + +protected: + /** + * Called when widget is resized + */ + void resizeEvent(QResizeEvent *); + /** + * \reimp + */ + void contextMenuEvent(QContextMenuEvent*); + /** + * does the dirty work + */ + void squeezeTextToLabel(); + +private slots: + void _k_copyFullText(); + +private: + QString fullText; + Qt::TextElideMode elideMode; +}; + + +#endif diff -r 43ddfa5e9fd0 -r d869e6a18f63 src/workstatuswidget.cpp --- a/src/workstatuswidget.cpp Tue Nov 15 14:47:19 2011 +0000 +++ b/src/workstatuswidget.cpp Tue Nov 15 16:02:18 2011 +0000 @@ -18,6 +18,7 @@ #include "workstatuswidget.h" #include "debug.h" #include "clickablelabel.h" +#include "squeezedlabel.h" #include #include @@ -47,15 +48,13 @@ f.setBold(true); m_openButton->setFont(f); m_openButton->setMouseUnderline(true); - m_openButton->setWordWrap(true); connect(m_openButton, SIGNAL(clicked()), this, SLOT(openButtonClicked())); - layout->addWidget(m_openButton, row, 2, 1, 2, Qt::AlignLeft); + layout->addWidget(m_openButton, row, 2, 1, 2); ++row; layout->addWidget(new QLabel(tr("Remote:")), row, 1); - m_remoteURLLabel = new QLabel; + m_remoteURLLabel = new SqueezedLabel; m_remoteURLLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - m_remoteURLLabel->setWordWrap(true); layout->addWidget(m_remoteURLLabel, row, 2, 1, 2); ++row; diff -r 43ddfa5e9fd0 -r d869e6a18f63 src/workstatuswidget.h --- a/src/workstatuswidget.h Tue Nov 15 14:47:19 2011 +0000 +++ b/src/workstatuswidget.h Tue Nov 15 16:02:18 2011 +0000 @@ -20,6 +20,8 @@ #include +class SqueezedLabel; + class QLabel; class QPushButton; class QFileInfo; @@ -51,7 +53,7 @@ ClickableLabel *m_openButton; QString m_remoteURL; - QLabel *m_remoteURLLabel; + SqueezedLabel *m_remoteURLLabel; QString m_state; QLabel *m_stateLabel;