diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2dca9e606a..fd823955db 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -123,6 +123,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 98c9e1ecb4..6dbe1148ef 100644
--- a/src/gui/DetailsWidget.cpp
+++ b/src/gui/DetailsWidget.cpp
@@ -34,7 +34,6 @@
namespace {
constexpr int GeneralTabIndex = 0;
-const QString hierarchySeparator(" / ");
}
DetailsWidget::DetailsWidget(QWidget* parent)
@@ -169,25 +168,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("****");
+ m_ui->entryPasswordLabel->setRawText("****");
+ m_ui->entryPasswordLabel->setToolTip(QString());
}
- 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(QString());
}
- m_ui->entryUrlLabel->setText(url);
const TimeInfo entryTime = m_currentEntry->timeInfo();
const QString expires = entryTime.expires() ? entryTime.expiryTime().toString(Qt::DefaultLocaleShortDate)
@@ -313,33 +312,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 7bea2e6310..5b5d698336 100644
--- a/src/gui/DetailsWidget.h
+++ b/src/gui/DetailsWidget.h
@@ -18,9 +18,10 @@
#ifndef KEEPASSX_DETAILSWIDGET_H
#define KEEPASSX_DETAILSWIDGET_H
-#include "gui/DatabaseWidget.h"
#include
+#include "gui/DatabaseWidget.h"
+
namespace Ui {
class DetailsWidget;
}
@@ -57,13 +58,12 @@ private slots:
void updateTotp();
void updateTabIndexes();
-
private:
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);
+ static QString hierarchy(const Group* group, const QString& title);
+
const QScopedPointer m_ui;
bool m_locked;
Entry* m_currentEntry;
diff --git a/src/gui/DetailsWidget.ui b/src/gui/DetailsWidget.ui
index 88c84ad431..5446f65106 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 0000000000..1642bdec8b
--- /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 0000000000..c7694b5a10
--- /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