keepassxc/src/gui/DetailsWidget.cpp

276 lines
8.5 KiB
C++
Raw Normal View History

/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "DetailsWidget.h"
#include "ui_DetailsWidget.h"
#include <QDebug>
#include "core/Config.h"
#include "core/FilePath.h"
#include "core/TimeInfo.h"
#include "gui/Clipboard.h"
2017-09-27 13:18:13 -04:00
#include "gui/DatabaseWidget.h"
DetailsWidget::DetailsWidget(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::DetailsWidget())
2017-09-27 13:18:13 -04:00
, m_locked(false)
, m_currentEntry(nullptr)
, m_currentGroup(nullptr)
{
m_ui->setupUi(this);
connect(parent, SIGNAL(pressedEntry(Entry*)), SLOT(getSelectedEntry(Entry*)));
connect(parent, SIGNAL(pressedGroup(Group*)), SLOT(getSelectedGroup(Group*)));
2017-09-27 13:18:13 -04:00
connect(parent, SIGNAL(currentModeChanged(DatabaseWidget::Mode)), SLOT(setDatabaseMode(DatabaseWidget::Mode)));
m_ui->totpButton->setIcon(filePath()->icon("actions", "chronometer"));
m_ui->closeButton->setIcon(filePath()->icon("actions", "dialog-close"));
connect(m_ui->totpButton, SIGNAL(toggled(bool)), SLOT(showTotp(bool)));
connect(m_ui->closeButton, SIGNAL(toggled(bool)), SLOT(hideDetails()));
this->hide();
}
DetailsWidget::~DetailsWidget()
{
}
void DetailsWidget::getSelectedEntry(Entry* selectedEntry)
{
m_currentEntry = selectedEntry;
if (!config()->get("GUI/HideDetailsView").toBool()) {
this->show();
}
m_ui->stackedWidget->setCurrentIndex(EntryPreview);
2017-09-27 13:18:13 -04:00
m_ui->tabWidget->setTabEnabled(AttributesTab, false);
m_ui->tabWidget->setTabEnabled(NotesTab, false);
m_ui->totpButton->hide();
m_ui->totpWidget->hide();
m_ui->totpButton->setChecked(false);
auto icon = m_currentEntry->iconPixmap();
if (icon.width() > 16 || icon.height() > 16) {
icon = icon.scaled(16, 16);
}
m_ui->entryIcon->setPixmap(icon);
QString title = QString(" / ");
Group* entry_group = m_currentEntry->group();
if (entry_group) {
QStringList hierarchy = entry_group->hierarchy();
hierarchy.removeFirst();
title += hierarchy.join(" / ");
if (hierarchy.size() > 0) {
title += " / ";
}
}
title.append(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->title()));
m_ui->titleLabel->setText(title);
m_ui->usernameLabel->setText(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->username()));
if (!config()->get("security/hidepassworddetails").toBool()) {
m_ui->passwordLabel->setText(shortPassword(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password())));
m_ui->passwordLabel->setToolTip(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()));
} else {
m_ui->passwordLabel->setText("****");
}
QString url = m_currentEntry->webUrl();
if (url != "") {
url = QString("<a href=\"%1\">%2</a>").arg(url).arg(shortUrl(url));
m_ui->urlLabel->setOpenExternalLinks(true);
} else {
url = shortUrl(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->url()));
m_ui->urlLabel->setOpenExternalLinks(false);
}
m_ui->urlLabel->setText(url);
TimeInfo entryTime = m_currentEntry->timeInfo();
if (entryTime.expires()) {
m_ui->expirationLabel->setText(entryTime.expiryTime().toString(Qt::DefaultLocaleShortDate));
} else {
m_ui->expirationLabel->setText(tr("Never"));
}
if (m_currentEntry->hasTotp()) {
m_ui->totpButton->show();
updateTotp();
m_step = m_currentEntry->totpStep();
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTotp()));
m_timer->start(m_step * 10);
}
2017-09-27 13:18:13 -04:00
QString notes = m_currentEntry->notes();
if (!notes.isEmpty()) {
m_ui->tabWidget->setTabEnabled(NotesTab, true);
m_ui->notesEdit->setText(m_currentEntry->resolveMultiplePlaceholders(notes));
}
QStringList customAttributes = m_currentEntry->attributes()->customKeys();
if (customAttributes.size() > 0) {
m_ui->tabWidget->setTabEnabled(AttributesTab, true);
m_ui->attributesEdit->clear();
QString attributesText = QString();
for (const QString& key : customAttributes) {
QString value = m_currentEntry->attributes()->value(key);
if (m_currentEntry->attributes()->isProtected(key)) {
value = "<i>[PROTECTED]</i>";
}
attributesText.append(QString("<b>%1</b>: %2<br/>").arg(key, value));
}
m_ui->attributesEdit->setText(attributesText);
}
}
void DetailsWidget::getSelectedGroup(Group* selectedGroup)
{
m_currentGroup = selectedGroup;
if (!config()->get("GUI/HideDetailsView").toBool()) {
this->show();
}
m_ui->stackedWidget->setCurrentIndex(GroupPreview);
2017-09-27 13:18:13 -04:00
m_ui->tabWidget->setTabEnabled(AttributesTab, false);
m_ui->tabWidget->setTabEnabled(NotesTab, false);
m_ui->totpButton->hide();
m_ui->totpWidget->hide();
auto icon = m_currentGroup->iconPixmap();
if (icon.width() > 32 || icon.height() > 32) {
icon = icon.scaled(32, 32);
}
m_ui->entryIcon->setPixmap(icon);
QString title = " / ";
2017-09-27 13:18:13 -04:00
QStringList hierarchy = m_currentGroup->hierarchy();
hierarchy.removeFirst();
title += hierarchy.join(" / ");
if (hierarchy.size() > 0) {
title += " / ";
}
m_ui->titleLabel->setText(title);
m_ui->notesEdit->setText(m_currentGroup->notes());
QString searching = tr("Disabled");
if (m_currentGroup->resolveSearchingEnabled()) {
searching = tr("Enabled");
}
m_ui->searchingLabel->setText(searching);
QString autotype = tr("Disabled");
if (m_currentGroup->resolveAutoTypeEnabled()) {
autotype = tr("Enabled");
}
m_ui->autotypeLabel->setText(autotype);
TimeInfo groupTime = m_currentGroup->timeInfo();
if (groupTime.expires()) {
m_ui->groupExpirationLabel->setText(groupTime.expiryTime().toString(Qt::DefaultLocaleShortDate));
} else {
m_ui->groupExpirationLabel->setText(tr("Never"));
}
m_ui->groupCreationLabel->setText(groupTime.creationTime().toString(Qt::DefaultLocaleShortDate));
m_ui->groupModifyLabel->setText(groupTime.lastModificationTime().toString(Qt::DefaultLocaleShortDate));
m_ui->groupAccessLabel->setText(groupTime.lastAccessTime().toString(Qt::DefaultLocaleShortDate));
}
void DetailsWidget::updateTotp()
{
2017-09-27 13:18:13 -04:00
if (m_locked) {
m_timer->stop();
return;
}
QString totpCode = m_currentEntry->totp();
QString firstHalf = totpCode.left(totpCode.size()/2);
QString secondHalf = totpCode.right(totpCode.size()/2);
m_ui->totpLabel->setText(firstHalf + " " + secondHalf);
}
void DetailsWidget::showTotp(bool visible)
{
if (visible){
m_ui->totpWidget->show();
} else {
m_ui->totpWidget->hide();
}
}
QString DetailsWidget::shortUrl(QString url)
{
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(QString password)
{
QString newpassword = "";
if (password.length() > 60) {
newpassword.append(password.left(50));
newpassword.append("...");
return newpassword;
}
return password;
}
void DetailsWidget::hideDetails()
{
this->hide();
}
2017-09-27 13:18:13 -04:00
void DetailsWidget::setDatabaseMode(DatabaseWidget::Mode mode)
{
m_locked = false;
if (mode == DatabaseWidget::LockedMode) {
m_locked = true;
return;
}
if (mode == DatabaseWidget::ViewMode) {
if (m_ui->stackedWidget->currentIndex() == GroupPreview) {
getSelectedGroup(m_currentGroup);
} else {
getSelectedEntry(m_currentEntry);
}
}
}
void DetailsWidget::copyToClipboard(const QString& text) {
clipboard()->setText(text);
}