diff --git a/app/savebar.cpp b/app/savebar.cpp --- a/app/savebar.cpp +++ b/app/savebar.cpp @@ -35,12 +35,14 @@ #include #include #include +#include // Local #include "lib/document/documentfactory.h" #include "lib/gwenviewconfig.h" #include "lib/memoryutils.h" #include "lib/paintutils.h" +#include "lib/squeezedlinklabel.h" namespace Gwenview { @@ -65,8 +67,10 @@ QToolButton* mSaveAsButton; QToolButton* mSaveAllButton; QToolButton* mSaveAllFullScreenButton; - QLabel* mMessageLabel; - QLabel* mActionsLabel; + KSqueezedTextLabel* mMessageLabel; + SqueezedLinkLabel* mPreviousActionsLabel; + QLabel* mActionsLabelSeparator; + SqueezedLinkLabel* mNextActionsLabel; QFrame* mTooManyChangesFrame; QUrl mCurrentUrl; @@ -168,7 +172,6 @@ void updateTopRowWidget(const QList& lst) { - QStringList links; QString message; if (lst.contains(mCurrentUrl)) { @@ -178,38 +181,47 @@ mRedoButton->show(); if (lst.size() > 1) { - QString previous = i18n("Previous modified image"); - QString next = i18n("Next modified image"); - if (mCurrentUrl == lst[0]) { - links << previous; - } else { - links << QStringLiteral("%1").arg(previous); - } - if (mCurrentUrl == lst[lst.size() - 1]) { - links << next; - } else { - links << QStringLiteral("%1").arg(next); - } + mPreviousActionsLabel->setText(i18n("Previous modified image"), + QStringLiteral("previous"), + mCurrentUrl == lst.first() ? SqueezedLinkLabel::PlainText + : SqueezedLinkLabel::Link); + mPreviousActionsLabel->show(); + mActionsLabelSeparator->show(); + mNextActionsLabel->setText(i18n("Next modified image"), + QStringLiteral("next"), + mCurrentUrl == lst.last() ? SqueezedLinkLabel::PlainText + : SqueezedLinkLabel::Link); + mNextActionsLabel->show(); + } else { + mPreviousActionsLabel->hide(); + mActionsLabelSeparator->hide(); + mNextActionsLabel->hide(); } } else { mUndoButton->hide(); mRedoButton->hide(); message = i18np("One image modified", "%1 images modified", lst.size()); + if (lst.size() > 1) { - links << QStringLiteral("%1").arg(i18n("Go to first modified image")); + mPreviousActionsLabel->setText(i18n("Go to first modified image"), QStringLiteral("first")); } else { - links << QStringLiteral("%1").arg(i18n("Go to it")); + mPreviousActionsLabel->setText(i18n("Go to it"), QStringLiteral("first")); } + mPreviousActionsLabel->show(); + mActionsLabelSeparator->hide(); + mNextActionsLabel->hide(); } mSaveCurrentUrlButton->setVisible(lst.contains(mCurrentUrl)); mSaveAsButton->setVisible(lst.contains(mCurrentUrl)); mSaveAllButton->setVisible(lst.size() >= 1); mMessageLabel->setText(message); - mMessageLabel->setMaximumWidth(mMessageLabel->minimumSizeHint().width()); - mActionsLabel->setText(links.join(" | ")); + mMessageLabel->setMaximumWidth(mMessageLabel->sizeHint().width()); + + mPreviousActionsLabel->setMaximumWidth(mPreviousActionsLabel->sizeHint().width()); + mNextActionsLabel->setMaximumWidth(mNextActionsLabel->sizeHint().width()); } void updateWidgetSizes() @@ -236,29 +248,37 @@ d->mSaveBarWidget->setObjectName(QLatin1String("saveBarWidget")); d->applyNormalStyleSheet(); - d->mMessageLabel = new QLabel; - d->mMessageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + d->mMessageLabel = new KSqueezedTextLabel; + d->mMessageLabel->setTextElideMode(Qt::ElideRight); d->mUndoButton = createToolButton(); d->mRedoButton = createToolButton(); d->mSaveCurrentUrlButton = createToolButton(); d->mSaveAsButton = createToolButton(); d->mSaveAllButton = createToolButton(); - d->mActionsLabel = new QLabel; - d->mActionsLabel->setAlignment(Qt::AlignCenter); - d->mActionsLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + d->mPreviousActionsLabel = new SqueezedLinkLabel; + d->mPreviousActionsLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + d->mActionsLabelSeparator = new QLabel(QStringLiteral("|")); + d->mNextActionsLabel = new SqueezedLinkLabel; d->createTooManyChangesFrame(); // Setup top row d->mTopRowWidget = new QWidget; QHBoxLayout* rowLayout = new QHBoxLayout(d->mTopRowWidget); - rowLayout->addWidget(d->mMessageLabel); - rowLayout->setStretchFactor(d->mMessageLabel, 1); + rowLayout->addWidget(d->mMessageLabel, 2); rowLayout->addWidget(d->mUndoButton); rowLayout->addWidget(d->mRedoButton); - rowLayout->addWidget(d->mActionsLabel); + + // Use flexible spacers instead of auto-expanding labels + // to center the whole group instead of the separator + rowLayout->addStretch(); + rowLayout->addWidget(d->mPreviousActionsLabel, 1); + rowLayout->addWidget(d->mActionsLabelSeparator); + rowLayout->addWidget(d->mNextActionsLabel, 1); + rowLayout->addStretch(); + rowLayout->addWidget(d->mSaveCurrentUrlButton); rowLayout->addWidget(d->mSaveAsButton); rowLayout->addWidget(d->mSaveAllButton); @@ -282,7 +302,8 @@ connect(DocumentFactory::instance(), SIGNAL(modifiedDocumentListChanged()), SLOT(updateContent())); - connect(d->mActionsLabel, &QLabel::linkActivated, this, &SaveBar::triggerAction); + connect(d->mPreviousActionsLabel, &QLabel::linkActivated, this, &SaveBar::triggerAction); + connect(d->mNextActionsLabel, &QLabel::linkActivated, this, &SaveBar::triggerAction); } SaveBar::~SaveBar() diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -137,6 +137,7 @@ jpegcontent.cpp kindproxymodel.cpp semanticinfo/sorteddirmodel.cpp + squeezedlinklabel.cpp memoryutils.cpp mimetypeutils.cpp paintutils.cpp diff --git a/lib/squeezedlinklabel.h b/lib/squeezedlinklabel.h new file mode 100644 --- /dev/null +++ b/lib/squeezedlinklabel.h @@ -0,0 +1,63 @@ +/* +Gwenview: an image viewer +Copyright 2018 Henrik Fehlauer + +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. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ +#ifndef SQUEEZEDLINKLABEL_H +#define SQUEEZEDLINKLABEL_H + +#include + +#include + +class SqueezedLinkLabelPrivate; + +/** + * KSqueezedTextLabel breaks eliding rich text content, but fixing + * that in QFontMetrics::elidedText in a generic way would be difficult. + * Therefore here we provide our own simplified label which can elide + * single-line links only. + * Since we cannot override KSqueezedTextLabel::squeezeTextToLabel, + * we derive from QLabel instead while still taking inspiration from + * KSqueezedTextLabel. + */ + +class GWENVIEWLIB_EXPORT SqueezedLinkLabel : public QLabel +{ +public: + enum LabelType { + PlainText, + Link + }; + + explicit SqueezedLinkLabel(QWidget* parent = nullptr); + + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + + void setText(const QString& text, const QString& linkTarget, const LabelType& labelType = Link); + +protected: + void resizeEvent(QResizeEvent*) override; + + void squeezeTextToLabel(); + +private: + SqueezedLinkLabelPrivate* const d; +}; + +#endif // SQUEEZEDLINKLABEL_H diff --git a/lib/squeezedlinklabel.cpp b/lib/squeezedlinklabel.cpp new file mode 100644 --- /dev/null +++ b/lib/squeezedlinklabel.cpp @@ -0,0 +1,83 @@ +/* +Gwenview: an image viewer +Copyright 2018 Henrik Fehlauer + +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. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "squeezedlinklabel.h" + +#include + +class SqueezedLinkLabelPrivate +{ +public: + QString fullText; + QString linkTarget; + SqueezedLinkLabel::LabelType labelType; +}; + +SqueezedLinkLabel::SqueezedLinkLabel(QWidget *parent) + : QLabel(parent), + d(new SqueezedLinkLabelPrivate) +{ + d->labelType = Link; +} + +QSize SqueezedLinkLabel::minimumSizeHint() const +{ + return QSize(-1, QLabel::minimumSizeHint().height()); +} + +QSize SqueezedLinkLabel::sizeHint() const +{ + const int textWidth = fontMetrics().width(d->fullText); + const int chromeWidth = width() - contentsRect().width(); // no support for indent and margin yet + return QSize(textWidth + chromeWidth, QLabel::sizeHint().height()); +} + +void SqueezedLinkLabel::setText(const QString& text, const QString& linkTarget, const LabelType& labelType) +{ + d->fullText = text; + d->linkTarget = linkTarget; + d->labelType = labelType; + squeezeTextToLabel(); +} + +void SqueezedLinkLabel::resizeEvent(QResizeEvent*) +{ + squeezeTextToLabel(); +} + +void SqueezedLinkLabel::squeezeTextToLabel() +{ + const int labelWidth = contentsRect().width(); + const int lineWidth = fontMetrics().width(d->fullText); + QString text; + + if (lineWidth > labelWidth) { + text = fontMetrics().elidedText(d->fullText, Qt::ElideRight, labelWidth); + setToolTip(d->fullText); + } else { + text = d->fullText; + setToolTip(QString()); + } + + if (d->labelType == Link) { + text = QStringLiteral("%1").arg(text, d->linkTarget); + } + QLabel::setText(text); +}