From b264614b9d55f9ab8f1e399d663f632660733385 Mon Sep 17 00:00:00 2001 From: frostasm Date: Fri, 29 Dec 2017 10:46:16 +0200 Subject: [PATCH] Use ElidedLabel in DetailsWidget --- src/CMakeLists.txt | 1 + src/gui/DetailsWidget.cpp | 45 +++---------- src/gui/DetailsWidget.h | 5 +- src/gui/DetailsWidget.ui | 65 +++++++++--------- src/gui/widgets/ElidedLabel.cpp | 116 ++++++++++++++++++++++++++++++++ src/gui/widgets/ElidedLabel.h | 61 +++++++++++++++++ 6 files changed, 222 insertions(+), 71 deletions(-) create mode 100644 src/gui/widgets/ElidedLabel.cpp create mode 100644 src/gui/widgets/ElidedLabel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f00e93531..ccdc955f2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,7 @@ set(keepassx_SOURCES gui/UnlockDatabaseWidget.cpp gui/UnlockDatabaseDialog.cpp gui/WelcomeWidget.cpp + gui/widgets/ElidedLabel.cpp gui/csvImport/CsvImportWidget.cpp gui/csvImport/CsvImportWizard.cpp gui/csvImport/CsvParserModel.cpp diff --git a/src/gui/DetailsWidget.cpp b/src/gui/DetailsWidget.cpp index 01519cbd0..1ac20c9d8 100644 --- a/src/gui/DetailsWidget.cpp +++ b/src/gui/DetailsWidget.cpp @@ -30,7 +30,6 @@ namespace { constexpr int GeneralTabIndex = 0; -const QString hierarchySeparator(" / "); } DetailsWidget::DetailsWidget(QWidget* parent) @@ -168,25 +167,25 @@ void DetailsWidget::updateEntryGeneralTab() if (!config()->get("security/hidepassworddetails").toBool()) { const QString password = m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()); - m_ui->entryPasswordLabel->setText(shortPassword(password)); + m_ui->entryPasswordLabel->setRawText(password); m_ui->entryPasswordLabel->setToolTip(password); } else { - m_ui->entryPasswordLabel->setText(QString("\u25cf").repeated(6)); + m_ui->entryPasswordLabel->setRawText(QString("\u25cf").repeated(6)); + m_ui->entryPasswordLabel->setToolTip({}); } - QString url = m_currentEntry->webUrl(); + const QString url = m_currentEntry->webUrl(); if (!url.isEmpty()) { // URL is well formed and can be opened in a browser // create a new display url that masks password placeholders // the actual link will use the password - url = QString("%2").arg(url).arg(shortUrl(m_currentEntry->displayUrl())); - m_ui->entryUrlLabel->setOpenExternalLinks(true); + m_ui->entryUrlLabel->setRawText(m_currentEntry->displayUrl()); + m_ui->entryUrlLabel->setUrl(url); } else { // Fallback to the raw url string - url = shortUrl(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->url())); - m_ui->entryUrlLabel->setOpenExternalLinks(false); + m_ui->entryUrlLabel->setRawText(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->url())); + m_ui->entryUrlLabel->setUrl({}); } - m_ui->entryUrlLabel->setText(url); const TimeInfo entryTime = m_currentEntry->timeInfo(); const QString expires = entryTime.expires() ? entryTime.expiryTime().toString(Qt::DefaultLocaleShortDate) @@ -251,7 +250,7 @@ void DetailsWidget::updateEntryAutotypeTab() void DetailsWidget::updateGroupHeaderLine() { Q_ASSERT(m_currentGroup); - m_ui->groupTitleLabel->setText(hierarchy(m_currentGroup, QString())); + m_ui->groupTitleLabel->setText(hierarchy(m_currentGroup, {})); m_ui->groupIcon->setPixmap(preparePixmap(m_currentGroup->iconPixmap(), 32)); } @@ -326,33 +325,11 @@ QPixmap DetailsWidget::preparePixmap(const QPixmap& pixmap, int size) return pixmap; } - -QString DetailsWidget::shortUrl(const QString& url) -{ - // TODO: create elided text - QString newurl = ""; - if (url.length() > 60) { - newurl.append(url.left(20)); - newurl.append("…"); - newurl.append(url.right(20)); - return newurl; - } - return url; -} - -QString DetailsWidget::shortPassword(const QString& password) -{ - // TODO: create elided text - if (password.length() > 60) { - return QString("%1…").arg(password.left(60)); - } - return password; -} - QString DetailsWidget::hierarchy(const Group* group, const QString& title) { + const QString separator(" / "); QStringList hierarchy = group->hierarchy(); hierarchy.removeFirst(); hierarchy.append(title); - return QString("%1%2").arg(hierarchySeparator, hierarchy.join(hierarchySeparator)); + return QString("%1%2").arg(separator, hierarchy.join(separator)); } diff --git a/src/gui/DetailsWidget.h b/src/gui/DetailsWidget.h index cc0ac779a..abec33400 100644 --- a/src/gui/DetailsWidget.h +++ b/src/gui/DetailsWidget.h @@ -61,10 +61,9 @@ private slots: void updateTabIndexes(); private: - void setTabEnabled(QTabWidget *tabWidget, QWidget* widget, bool enabled); + void setTabEnabled(QTabWidget* tabWidget, QWidget* widget, bool enabled); + static QPixmap preparePixmap(const QPixmap& pixmap, int size); - static QString shortUrl(const QString& url); - static QString shortPassword(const QString& password); static QString hierarchy(const Group* group, const QString& title); const QScopedPointer m_ui; diff --git a/src/gui/DetailsWidget.ui b/src/gui/DetailsWidget.ui index 88c84ad43..5446f6510 100644 --- a/src/gui/DetailsWidget.ui +++ b/src/gui/DetailsWidget.ui @@ -152,7 +152,7 @@ - + @@ -196,6 +196,12 @@ + + + 100 + 0 + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse @@ -224,7 +230,14 @@ - + + + + 100 + 0 + + + @@ -249,12 +262,12 @@ - - - - 0 - 0 - + + + + 100 + 0 + PointingHandCursor @@ -297,7 +310,7 @@ 20 - 40 + 10 @@ -530,14 +543,7 @@ - - - - 0 - 0 - - - + @@ -562,14 +568,7 @@ - - - - 0 - 0 - - - + @@ -594,14 +593,7 @@ - - - - 0 - 0 - - - + @@ -611,7 +603,7 @@ 20 - 40 + 10 @@ -663,6 +655,11 @@
gui/entry/EntryAttachmentsWidget.h
1 + + ElidedLabel + QLabel +
gui/widgets/ElidedLabel.h
+
diff --git a/src/gui/widgets/ElidedLabel.cpp b/src/gui/widgets/ElidedLabel.cpp new file mode 100644 index 000000000..1642bdec8 --- /dev/null +++ b/src/gui/widgets/ElidedLabel.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 or (at your option) + * version 3 of the License. + * + * 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, see . + */ + +#include "ElidedLabel.h" + +#include +#include + +namespace { +const QString htmlLinkTemplate("%2"); +} + +ElidedLabel::ElidedLabel(QWidget* parent, Qt::WindowFlags f) + : QLabel(parent, f) + , m_elideMode(Qt::ElideMiddle) +{ + connect(this, SIGNAL(elideModeChanged(Qt::TextElideMode)), this, SLOT(updateElidedText())); + connect(this, SIGNAL(rawTextChanged(QString)), this, SLOT(updateElidedText())); + connect(this, SIGNAL(urlChanged(QString)), this, SLOT(updateElidedText())); +} + +ElidedLabel::ElidedLabel(const QString& text, QWidget* parent, Qt::WindowFlags f) + : ElidedLabel(parent, f) +{ + setText(text); +} + +Qt::TextElideMode ElidedLabel::elideMode() const +{ + return m_elideMode; +} + +QString ElidedLabel::rawText() const +{ + return m_rawText; +} + +QString ElidedLabel::url() const +{ + return m_url; +} + +void ElidedLabel::setElideMode(Qt::TextElideMode elideMode) +{ + if (m_elideMode == elideMode) + return; + + if (m_elideMode != Qt::ElideNone) { + setWordWrap(false); + } + + m_elideMode = elideMode; + emit elideModeChanged(m_elideMode); +} + +void ElidedLabel::setRawText(const QString& elidedText) +{ + if (m_rawText == elidedText) + return; + + m_rawText = elidedText; + emit rawTextChanged(m_rawText); +} + +void ElidedLabel::setUrl(const QString& url) +{ + if (m_url == url) + return; + + m_url = url; + emit urlChanged(m_url); +} + +void ElidedLabel::clear() +{ + setRawText(QString()); + setElideMode(Qt::ElideMiddle); + setUrl(QString()); + QLabel::clear(); +} + +void ElidedLabel::updateElidedText() +{ + if (m_rawText.isEmpty()) { + QLabel::clear(); + return; + } + + QString displayText = m_rawText; + if (m_elideMode != Qt::ElideNone) { + const QFontMetrics metrix(font()); + displayText = metrix.elidedText(m_rawText, m_elideMode, width() - 2); + } + setText(m_url.isEmpty() ? displayText : htmlLinkTemplate.arg(m_url, displayText)); + setOpenExternalLinks(!m_url.isEmpty()); +} + +void ElidedLabel::resizeEvent(QResizeEvent* event) +{ + updateElidedText(); + QLabel::resizeEvent(event); +} diff --git a/src/gui/widgets/ElidedLabel.h b/src/gui/widgets/ElidedLabel.h new file mode 100644 index 000000000..c7694b5a1 --- /dev/null +++ b/src/gui/widgets/ElidedLabel.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 or (at your option) + * version 3 of the License. + * + * 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, see . + */ + +#ifndef KEEPASSX_ELIDEDLABEL_H +#define KEEPASSX_ELIDEDLABEL_H + +#include + +class QResizeEvent; + +class ElidedLabel : public QLabel +{ + Q_OBJECT + Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode NOTIFY elideModeChanged) + Q_PROPERTY(QString rawText READ rawText WRITE setRawText NOTIFY rawTextChanged) + Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) +public: + explicit ElidedLabel(QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags()); + explicit ElidedLabel(const QString &text, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags()); + + Qt::TextElideMode elideMode() const; + QString rawText() const; + QString url() const; + +public slots: + void setElideMode(Qt::TextElideMode elideMode); + void setRawText(const QString& rawText); + void setUrl(const QString& url); + void clear(); + +signals: + void elideModeChanged(Qt::TextElideMode elideMode); + void rawTextChanged(QString rawText); + void urlChanged(QString url); + +private slots: + void updateElidedText(); + +private: + void resizeEvent(QResizeEvent* event); + + Qt::TextElideMode m_elideMode; + QString m_rawText; + QString m_url; +}; + +#endif // KEEPASSX_ELIDEDLABEL_H