diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 37e4bdd68..e57cdb3c7 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -22,10 +22,10 @@ install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database) if(UNIX AND NOT APPLE) install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor FILES_MATCHING PATTERN "keepassx*.png" PATTERN "keepassx*.svgz" - PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE) + PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor FILES_MATCHING PATTERN "application-x-keepassxc.png" PATTERN "application-x-keepassxc.svgz" - PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE) + PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) install(FILES linux/keepassxc.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) install(FILES linux/keepassxc.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) endif(UNIX AND NOT APPLE) diff --git a/share/icons/application/32x32/actions/document-edit.png b/share/icons/application/32x32/actions/document-edit.png new file mode 100644 index 000000000..eb327b0a1 Binary files /dev/null and b/share/icons/application/32x32/actions/document-edit.png differ diff --git a/share/icons/application/32x32/actions/document-properties.png b/share/icons/application/32x32/actions/document-properties.png new file mode 100644 index 000000000..a6d13863d Binary files /dev/null and b/share/icons/application/32x32/actions/document-properties.png differ diff --git a/share/icons/application/32x32/actions/key-enter.png b/share/icons/application/32x32/actions/key-enter.png new file mode 100644 index 000000000..60d11e2f1 Binary files /dev/null and b/share/icons/application/32x32/actions/key-enter.png differ diff --git a/share/icons/application/32x32/actions/view-history.png b/share/icons/application/32x32/actions/view-history.png new file mode 100644 index 000000000..a67c689ac Binary files /dev/null and b/share/icons/application/32x32/actions/view-history.png differ diff --git a/share/icons/application/32x32/apps/internet-web-browser.png b/share/icons/application/32x32/apps/internet-web-browser.png new file mode 100644 index 000000000..b4106a58b Binary files /dev/null and b/share/icons/application/32x32/apps/internet-web-browser.png differ diff --git a/share/icons/application/32x32/apps/preferences-desktop-icons.png b/share/icons/application/32x32/apps/preferences-desktop-icons.png new file mode 100644 index 000000000..dcd605b25 Binary files /dev/null and b/share/icons/application/32x32/apps/preferences-desktop-icons.png differ diff --git a/share/icons/application/32x32/categories/preferences-other.png b/share/icons/application/32x32/categories/preferences-other.png new file mode 100644 index 000000000..acafe44c6 Binary files /dev/null and b/share/icons/application/32x32/categories/preferences-other.png differ diff --git a/share/icons/application/32x32/status/security-high.png b/share/icons/application/32x32/status/security-high.png new file mode 100644 index 000000000..7178893c2 Binary files /dev/null and b/share/icons/application/32x32/status/security-high.png differ diff --git a/share/icons/svg/document-properties.svgz b/share/icons/svg/document-properties.svgz new file mode 100644 index 000000000..7f166d7f2 Binary files /dev/null and b/share/icons/svg/document-properties.svgz differ diff --git a/share/icons/svg/internet-web-browser.svgz b/share/icons/svg/internet-web-browser.svgz new file mode 100644 index 000000000..f48f1415c Binary files /dev/null and b/share/icons/svg/internet-web-browser.svgz differ diff --git a/share/icons/svg/key-enter.svgz b/share/icons/svg/key-enter.svgz new file mode 100644 index 000000000..7176b5acb Binary files /dev/null and b/share/icons/svg/key-enter.svgz differ diff --git a/share/icons/svg/preferences-desktop-icons.svgz b/share/icons/svg/preferences-desktop-icons.svgz new file mode 100644 index 000000000..1cd0a0526 Binary files /dev/null and b/share/icons/svg/preferences-desktop-icons.svgz differ diff --git a/share/icons/svg/preferences-other.svgz b/share/icons/svg/preferences-other.svgz new file mode 100644 index 000000000..4abeca376 Binary files /dev/null and b/share/icons/svg/preferences-other.svgz differ diff --git a/share/icons/svg/security-high.svgz b/share/icons/svg/security-high.svgz new file mode 100644 index 000000000..5edee3734 Binary files /dev/null and b/share/icons/svg/security-high.svgz differ diff --git a/share/icons/svg/view-history.svgz b/share/icons/svg/view-history.svgz new file mode 100644 index 000000000..fff230f66 Binary files /dev/null and b/share/icons/svg/view-history.svgz differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e27c24928..380a6c2dd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,6 +70,7 @@ set(keepassx_SOURCES format/KeePass2XmlWriter.cpp gui/AboutDialog.cpp gui/Application.cpp + gui/CategoryListWidget.cpp gui/ChangeMasterKeyWidget.cpp gui/Clipboard.cpp gui/DatabaseOpenWidget.cpp @@ -134,6 +135,7 @@ set(keepassx_FORMS gui/ChangeMasterKeyWidget.ui gui/DatabaseOpenWidget.ui gui/DatabaseSettingsWidget.ui + gui/CategoryListWidget.ui gui/EditWidget.ui gui/EditWidgetIcons.ui gui/EditWidgetProperties.ui diff --git a/src/core/Config.cpp b/src/core/Config.cpp index d5365d7c1..28b17536f 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -102,10 +102,11 @@ void Config::init(const QString& fileName) m_defaults.insert("MinimizeOnCopy", false); m_defaults.insert("UseGroupIconOnEntryCreation", false); m_defaults.insert("AutoTypeEntryTitleMatch", true); + m_defaults.insert("UseGroupIconOnEntryCreation", true); m_defaults.insert("security/clearclipboard", true); m_defaults.insert("security/clearclipboardtimeout", 10); m_defaults.insert("security/lockdatabaseidle", false); - m_defaults.insert("security/lockdatabaseidlesec", 10); + m_defaults.insert("security/lockdatabaseidlesec", 240); m_defaults.insert("security/lockdatabaseminimize", false); m_defaults.insert("security/passwordsrepeat", false); m_defaults.insert("security/passwordscleartext", false); diff --git a/src/gui/AboutDialog.cpp b/src/gui/AboutDialog.cpp index a4f180b05..636b284f9 100644 --- a/src/gui/AboutDialog.cpp +++ b/src/gui/AboutDialog.cpp @@ -23,15 +23,21 @@ #include "core/FilePath.h" #include "crypto/Crypto.h" +#include +#include + AboutDialog::AboutDialog(QWidget* parent) - : QDialog(parent) - , m_ui(new Ui::AboutDialog()) + : QDialog(parent), + m_ui(new Ui::AboutDialog()) { m_ui->setupUi(this); + resize(minimumSize()); + setWindowFlags(Qt::Sheet); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + m_ui->nameLabel->setText(m_ui->nameLabel->text() + " " + KEEPASSX_VERSION); QFont nameLabelFont = m_ui->nameLabel->font(); - nameLabelFont.setBold(true); nameLabelFont.setPointSize(nameLabelFont.pointSize() + 4); m_ui->nameLabel->setFont(nameLabelFont); @@ -45,37 +51,56 @@ AboutDialog::AboutDialog(QWidget* parent) commitHash = DIST_HASH; } + QString debugInfo = "KeePassXC - "; + debugInfo.append(tr("Version %1\n").arg(KEEPASSX_VERSION)); if (!commitHash.isEmpty()) { - QString labelText = tr("Revision").append(": ").append(commitHash); - m_ui->label_git->setText(labelText); + debugInfo.append(tr("Revision: %1").arg(commitHash).append("\n\n")); } - QString libs = QString("%1\n- Qt %2\n- %3") - .arg(m_ui->label_libs->text()) - .arg(QString::fromLocal8Bit(qVersion())) - .arg(Crypto::backendVersion()); - m_ui->label_libs->setText(libs); + debugInfo.append(QString("%1\n- Qt %2\n- %3\n\n") + .arg(tr("Libraries:")) + .arg(QString::fromLocal8Bit(qVersion())) + .arg(Crypto::backendVersion())); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4") + .arg(QSysInfo::prettyProductName()) + .arg(QSysInfo::currentCpuArchitecture()) + .arg(QSysInfo::kernelType()) + .arg(QSysInfo::kernelVersion())); + + debugInfo.append("\n\n"); +#endif QString extensions; #ifdef WITH_XC_HTTP - extensions += "- KeePassHTTP\n"; + extensions += "\n- KeePassHTTP"; #endif #ifdef WITH_XC_AUTOTYPE - extensions += "- Autotype\n"; + extensions += "\n- Auto-Type"; #endif #ifdef WITH_XC_YUBIKEY - extensions += "- Yubikey\n"; + extensions += "\n- YubiKey"; #endif if (extensions.isEmpty()) - extensions = "None"; + extensions = " None"; - m_ui->label_features->setText(m_ui->label_features->text() + extensions); + debugInfo.append(tr("Enabled extensions:").append(extensions)); + + m_ui->debugInfo->setPlainText(debugInfo); setAttribute(Qt::WA_DeleteOnClose); connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close())); + connect(m_ui->copyToClipboard, SIGNAL(clicked()), SLOT(copyToClipboard())); } AboutDialog::~AboutDialog() { } + +void AboutDialog::copyToClipboard() +{ + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(m_ui->debugInfo->toPlainText()); +} diff --git a/src/gui/AboutDialog.h b/src/gui/AboutDialog.h index 08db6c887..b69a14dbb 100644 --- a/src/gui/AboutDialog.h +++ b/src/gui/AboutDialog.h @@ -33,6 +33,9 @@ public: explicit AboutDialog(QWidget* parent = nullptr); ~AboutDialog(); +protected slots: + void copyToClipboard(); + private: QScopedPointer m_ui; }; diff --git a/src/gui/AboutDialog.ui b/src/gui/AboutDialog.ui index 28f4dd0c4..e1e706808 100644 --- a/src/gui/AboutDialog.ui +++ b/src/gui/AboutDialog.ui @@ -6,20 +6,23 @@ 0 0 - 455 - 266 + 479 + 478 About KeePassXC - - - QLayout::SetFixedSize - + - + + 15 + + + 20 + + @@ -27,9 +30,21 @@ 0 + + + 48 + 48 + + + + + 48 + 48 + + - + @@ -37,6 +52,12 @@ 0 + + + 75 + true + + KeePassXC @@ -45,66 +66,161 @@ - - - - 0 - 0 - - - - <a href="https://keepassxc.org/">https://keepassxc.org/</a> - - - true - - - - - - - - 0 - 0 - - - - KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3. - - - true - - - - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Using: - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - Extensions: - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + 0 + + + About + + + + + + + 0 + 0 + + + + <p>Website: <a href="https://keepassxc.org/">https://keepassxc.org/</a></p> + + + true + + + + + + + <p>Report bugs at: <a href="https://github.com/keepassxreboot/keepassxc/issues">https://github.com/</a></p> + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + + 0 + 0 + + + + KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3. + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 5 + + + + + + + + + 0 + 0 + + + + <p>Main contributors:</p> +<ul> +<li>debfx (KeePassX)</li> +<li>droidmonkey</li> +<li>louib</li> +<li>phoerious<li> +<li>thezero</li> +</ul> + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Debug Info + + + + + + + 0 + 0 + + + + Include the following information whenever you report a bug: + + + + + + + + 0 + 0 + + + + true + + + + + + + Copy to clipboard + + + + + diff --git a/src/gui/CategoryListWidget.cpp b/src/gui/CategoryListWidget.cpp new file mode 100644 index 000000000..c93ac46e7 --- /dev/null +++ b/src/gui/CategoryListWidget.cpp @@ -0,0 +1,252 @@ +/* + * 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 "CategoryListWidget.h" +#include "ui_CategoryListWidget.h" + +#include +#include +#include +#include +#include + +CategoryListWidget::CategoryListWidget(QWidget* parent) + : QWidget(parent), + m_itemDelegate(nullptr), + m_ui(new Ui::CategoryListWidget()) +{ + m_ui->setupUi(this); + m_itemDelegate = new CategoryListWidgetDelegate(m_ui->categoryList); + m_ui->categoryList->setItemDelegate(m_itemDelegate); + + connect(m_ui->categoryList, SIGNAL(currentRowChanged(int)), SLOT(emitCategoryChanged(int))); + + connect(m_ui->scrollUp, SIGNAL(clicked()), SLOT(scrollCategoriesUp())); + connect(m_ui->scrollDown, SIGNAL(clicked()), SLOT(scrollCategoriesDown())); + connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(updateCategoryScrollButtons())); + connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), SLOT(updateCategoryScrollButtons())); +} + +CategoryListWidget::~CategoryListWidget() +{ +} + +QSize CategoryListWidget::sizeHint() const +{ + QSize sizeHint = QWidget::sizeHint(); + + int width = m_ui->categoryList->width(); + + int min = minimumSizeHint().width(); + if (width < min) { + width = min; + } + sizeHint.setWidth(width); + + return sizeHint; +} + +QSize CategoryListWidget::minimumSizeHint() const +{ + return QSize(m_itemDelegate->minWidth() + m_ui->categoryList->frameWidth() * 2, + m_ui->categoryList->sizeHintForRow(0) * 2); +} + +int CategoryListWidget::addCategory(const QString& labelText, const QIcon& icon) +{ + QListWidgetItem* item = new QListWidgetItem(m_ui->categoryList); + item->setText(labelText); + item->setIcon(icon); + m_ui->categoryList->addItem(item); + return m_ui->categoryList->count() - 1; +} + +void CategoryListWidget::removeCategory(int index) +{ + m_ui->categoryList->removeItemWidget(m_ui->categoryList->item(index)); +} + +int CategoryListWidget::currentCategory() +{ + return m_ui->categoryList->currentRow(); +} + +void CategoryListWidget::setCurrentCategory(int index) +{ + m_ui->categoryList->setCurrentRow(index); +} + +void CategoryListWidget::setCategoryHidden(int index, bool hidden) +{ + m_ui->categoryList->item(index)->setHidden(hidden); +} + +bool CategoryListWidget::isCategoryHidden(int index) +{ + return m_ui->categoryList->item(index)->isHidden(); +} + +void CategoryListWidget::showEvent(QShowEvent* event) +{ + QWidget::showEvent(event); + updateCategoryScrollButtons(); +} + +void CategoryListWidget::resizeEvent(QResizeEvent* event) +{ + auto newDelegate = new CategoryListWidgetDelegate(m_ui->categoryList); + m_ui->categoryList->setItemDelegate(newDelegate); + m_itemDelegate->deleteLater(); + m_itemDelegate = newDelegate; + + QWidget::resizeEvent(event); +} + +void CategoryListWidget::updateCategoryScrollButtons() +{ + m_ui->scrollUp->setEnabled(m_ui->categoryList->verticalScrollBar()->value() != 0); + m_ui->scrollDown->setEnabled(m_ui->categoryList->verticalScrollBar()->value() + != m_ui->categoryList->verticalScrollBar()->maximum()); + + m_ui->scrollUp->setVisible(m_ui->categoryList->verticalScrollBar()->maximum() > 0); + m_ui->scrollDown->setVisible(m_ui->scrollUp->isVisible()); +} + +void CategoryListWidget::scrollCategoriesUp() +{ + m_ui->categoryList->verticalScrollBar()->setValue( + m_ui->categoryList->verticalScrollBar()->value() - m_ui->categoryList->verticalScrollBar()->pageStep() + ); +} + +void CategoryListWidget::scrollCategoriesDown() +{ + m_ui->categoryList->verticalScrollBar()->setValue( + m_ui->categoryList->verticalScrollBar()->value() + m_ui->categoryList->verticalScrollBar()->pageStep() + ); +} + +void CategoryListWidget::emitCategoryChanged(int index) +{ + emit categoryChanged(index); +} + + +/* =============================================================================================== */ + + +CategoryListWidgetDelegate::CategoryListWidgetDelegate(QListWidget* parent) + : QStyledItemDelegate(parent), + m_listWidget(parent), + m_size(minWidth(), 96) +{ + if (m_listWidget && m_listWidget->width() > m_size.width()) { + m_size.setWidth(m_listWidget->width()); + } +} + +#ifdef Q_OS_WIN +#include +class WindowsCorrectedStyle : public QProxyStyle +{ +public: + void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override + { + painter->save(); + + if (PE_PanelItemViewItem == element) { + // Qt on Windows draws selection backgrounds only for the actual text/icon + // bounding box, not over the full width of a list item. + // We therefore need to translate and stretch the painter before we can + // tell Qt to draw its native styles. + // Since we are scaling horizontally, we also need to move the right and left + // edge pixels outside the drawing area to avoid thick border lines. + QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(1, 0, 1, 0); + painter->scale(static_cast(option->rect.width()) / itemRect.width(), 1.0); + painter->translate(option->rect.left() - itemRect.left() + 1, 0); + } + QProxyStyle::drawPrimitive(element, option, painter, widget); + + painter->restore(); + } +}; +#endif + +void CategoryListWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + painter->save(); + + QIcon icon = opt.icon; + QSize iconSize = opt.icon.actualSize(QSize(ICON_SIZE, ICON_SIZE)); + opt.icon = QIcon(); + opt.decorationAlignment = Qt::AlignHCenter | Qt::AlignVCenter; + opt.decorationPosition = QStyleOptionViewItem::Top; + +#ifdef Q_OS_WIN + QScopedPointer style(new WindowsCorrectedStyle()); +#else + QStyle* style = opt.widget ? opt.widget->style() : QApplication::style(); +#endif + + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); + + QRect fontRect = painter->fontMetrics().boundingRect( + QRect(0, 0, minWidth(), m_size.height()), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextWordWrap, opt.text); + + int paddingTop = fontRect.height() < 30 ? 15 : 10; + int left = opt.rect.left() + opt.rect.width() / 2 - iconSize.width() / 2; + painter->drawPixmap(left, opt.rect.top() + paddingTop, icon.pixmap(iconSize)); + + painter->restore(); +} + +int CategoryListWidgetDelegate::minWidth() const +{ + int c = m_listWidget->count(); + int maxWidth = 0; + + for (int i = 0; i < c; ++i) { + QFontMetrics fm(m_listWidget->font()); + QRect fontRect = fm.boundingRect( + QRect(0, 0, 0, 0), Qt::TextWordWrap | Qt::ElideNone, m_listWidget->item(i)->text()); + + if (fontRect.width() > maxWidth) { + maxWidth = fontRect.width(); + } + } + + // add some padding + maxWidth += 10; + + return maxWidth < m_size.height() ? m_size.height() : maxWidth; +} + +QSize CategoryListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option); + Q_UNUSED(index); + + int w = minWidth(); + if (m_listWidget->width() > w) { + w = m_listWidget->width(); + } + + return QSize(w, m_size.height()); +} diff --git a/src/gui/CategoryListWidget.h b/src/gui/CategoryListWidget.h new file mode 100644 index 000000000..3cf82fd1b --- /dev/null +++ b/src/gui/CategoryListWidget.h @@ -0,0 +1,90 @@ +/* + * 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 +#include +#include + +class CategoryListWidgetDelegate; +class QListWidget; + +namespace Ui { + class CategoryListWidget; +} + +class CategoryListWidget : public QWidget +{ + Q_OBJECT + +public: + CategoryListWidget(QWidget* parent = 0); + ~CategoryListWidget(); + + int currentCategory(); + void setCurrentCategory(int index); + int addCategory(const QString& labelText, const QIcon& icon); + void setCategoryHidden(int index, bool hidden); + bool isCategoryHidden(int index); + void removeCategory(int index); + +signals: + void categoryChanged(int index); + +protected: + void showEvent(QShowEvent* event) override; + void resizeEvent(QResizeEvent * event) override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + +protected slots: + void updateCategoryScrollButtons(); + void scrollCategoriesDown(); + void scrollCategoriesUp(); + void emitCategoryChanged(int index); + +private: + QPointer m_itemDelegate; + const QScopedPointer m_ui; + + Q_DISABLE_COPY(CategoryListWidget) +}; + + +/* =============================================================================================== */ + + +class CategoryListWidgetDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit CategoryListWidgetDelegate(QListWidget* parent = nullptr); + int minWidth() const; + +protected: + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +private: + + const int ICON_SIZE = 32; + + QPointer m_listWidget; + QSize m_size; + + Q_DISABLE_COPY(CategoryListWidgetDelegate) +}; diff --git a/src/gui/CategoryListWidget.ui b/src/gui/CategoryListWidget.ui new file mode 100644 index 000000000..f16165cdb --- /dev/null +++ b/src/gui/CategoryListWidget.ui @@ -0,0 +1,122 @@ + + + CategoryListWidget + + + + 0 + 0 + 182 + 418 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 15 + + + + + + + Qt::UpArrow + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QListView::Static + + + QListView::TopToBottom + + + false + + + QListView::IconMode + + + true + + + true + + + + + + + + 0 + 0 + + + + + 16777215 + 15 + + + + + + + Qt::DownArrow + + + + + + + categoryList + scrollUp + scrollDown + + + + diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 9af79f777..9bdd9ce90 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -287,7 +287,7 @@ void DatabaseWidget::createEntry() void DatabaseWidget::setIconFromParent() { - if (!config()->get("UseGroupIconOnEntryCreation").toBool()) { + if (!config()->get("UseGroupIconOnEntryCreation", true).toBool()) { return; } diff --git a/src/gui/EditWidget.cpp b/src/gui/EditWidget.cpp index ef29f0132..24cc64fec 100644 --- a/src/gui/EditWidget.cpp +++ b/src/gui/EditWidget.cpp @@ -18,6 +18,8 @@ #include "EditWidget.h" #include "ui_EditWidget.h" +#include "core/FilePath.h" + EditWidget::EditWidget(QWidget* parent) : DialogyWidget(parent) , m_ui(new Ui::EditWidget()) @@ -32,7 +34,7 @@ EditWidget::EditWidget(QWidget* parent) headerLabelFont.setPointSize(headerLabelFont.pointSize() + 2); headlineLabel()->setFont(headerLabelFont); - connect(m_ui->categoryList, SIGNAL(currentRowChanged(int)), + connect(m_ui->categoryList, SIGNAL(categoryChanged(int)), m_ui->stackedWidget, SLOT(setCurrentIndex(int))); connect(m_ui->buttonBox, SIGNAL(accepted()), SIGNAL(accepted())); @@ -43,23 +45,32 @@ EditWidget::~EditWidget() { } -void EditWidget::add(const QString& labelText, QWidget* widget) +void EditWidget::addPage(const QString& labelText, const QIcon& icon, QWidget* widget) { - m_ui->categoryList->addItem(labelText); m_ui->stackedWidget->addWidget(widget); + m_ui->categoryList->addCategory(labelText, icon); } -void EditWidget::setRowHidden(QWidget* widget, bool hide) +void EditWidget::setPageHidden(QWidget* widget, bool hidden) { - int row = m_ui->stackedWidget->indexOf(widget); - if (row != -1) { - m_ui->categoryList->item(row)->setHidden(hide); + int index = m_ui->stackedWidget->indexOf(widget); + if (index != -1) { + m_ui->categoryList->setCategoryHidden(index, hidden); + } + + if (index == m_ui->stackedWidget->currentIndex()) { + int newIndex = m_ui->stackedWidget->currentIndex() - 1; + if (newIndex < 0) { + newIndex = m_ui->stackedWidget->count() - 1; + } + m_ui->stackedWidget->setCurrentIndex(newIndex); } } -void EditWidget::setCurrentRow(int index) +void EditWidget::setCurrentPage(int index) { - m_ui->categoryList->setCurrentRow(index); + m_ui->categoryList->setCurrentCategory(index); + m_ui->stackedWidget->setCurrentIndex(index); } void EditWidget::setHeadline(const QString& text) diff --git a/src/gui/EditWidget.h b/src/gui/EditWidget.h index 6f2c8f2dc..46951de41 100644 --- a/src/gui/EditWidget.h +++ b/src/gui/EditWidget.h @@ -19,6 +19,8 @@ #define KEEPASSX_EDITWIDGET_H #include +#include +#include #include "gui/DialogyWidget.h" #include "gui/MessageWidget.h" @@ -37,19 +39,19 @@ public: explicit EditWidget(QWidget* parent = nullptr); ~EditWidget(); - void add(const QString& labelText, QWidget* widget); - void setRowHidden(QWidget* widget, bool hide); - void setCurrentRow(int index); + void addPage(const QString& labelText, const QIcon& icon, QWidget* widget); + void setPageHidden(QWidget* widget, bool hidden); + void setCurrentPage(int index); void setHeadline(const QString& text); QLabel* headlineLabel(); void setReadOnly(bool readOnly); bool readOnly() const; -Q_SIGNALS: +signals: void accepted(); void rejected(); -protected Q_SLOTS: +protected slots: void showMessage(const QString& text, MessageWidget::MessageType type); void hideMessage(); diff --git a/src/gui/EditWidget.ui b/src/gui/EditWidget.ui index 64baf7032..6afce9f3e 100644 --- a/src/gui/EditWidget.ui +++ b/src/gui/EditWidget.ui @@ -38,9 +38,16 @@ - + - + + + + 0 + 0 + + + @@ -52,7 +59,7 @@ - + 5 @@ -76,13 +83,11 @@ CategoryListWidget - QListWidget -
gui/entry/EditEntryWidget_p.h
+ QWidget +
gui/CategoryListWidget.h
+ 1
- - categoryList - diff --git a/src/gui/KMessageWidget.cpp b/src/gui/KMessageWidget.cpp index f2c48c253..e2c22574c 100644 --- a/src/gui/KMessageWidget.cpp +++ b/src/gui/KMessageWidget.cpp @@ -277,7 +277,7 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type) bg1 = palette().highlight().color(); break; case Warning: - bg1.setRgb(176, 128, 0); // values taken from kcolorscheme.cpp (Neutral) + bg1.setRgb(181, 102, 0); // values taken from kcolorscheme.cpp (Neutral) break; case Error: bg1.setRgb(191, 3, 3); // values taken from kcolorscheme.cpp (Negative) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 9a9ef3dcf..1258d9f6e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -54,34 +54,47 @@ #ifdef WITH_XC_HTTP class HttpPlugin: public ISettingsPage { - public: - HttpPlugin(DatabaseTabWidget * tabWidget) { - m_service = new Service(tabWidget); - } - virtual ~HttpPlugin() { - //delete m_service; - } - virtual QString name() { - return QObject::tr("Http"); - } - virtual QWidget * createWidget() { - OptionDialog * dlg = new OptionDialog(); - QObject::connect(dlg, SIGNAL(removeSharedEncryptionKeys()), m_service, SLOT(removeSharedEncryptionKeys())); - QObject::connect(dlg, SIGNAL(removeStoredPermissions()), m_service, SLOT(removeStoredPermissions())); - return dlg; - } - virtual void loadSettings(QWidget * widget) { - qobject_cast(widget)->loadSettings(); - } - virtual void saveSettings(QWidget * widget) { - qobject_cast(widget)->saveSettings(); - if (HttpSettings::isEnabled()) - m_service->start(); - else - m_service->stop(); - } - private: - Service *m_service; +public: + HttpPlugin(DatabaseTabWidget * tabWidget) + { + m_service = new Service(tabWidget); + } + + ~HttpPlugin() = default; + + QString name() override + { + return QObject::tr("Browser Integration"); + } + + QIcon icon() override + { + return FilePath::instance()->icon("apps", "internet-web-browser"); + } + + QWidget * createWidget() override + { + OptionDialog * dlg = new OptionDialog(); + QObject::connect(dlg, SIGNAL(removeSharedEncryptionKeys()), m_service, SLOT(removeSharedEncryptionKeys())); + QObject::connect(dlg, SIGNAL(removeStoredPermissions()), m_service, SLOT(removeStoredPermissions())); + return dlg; + } + + void loadSettings(QWidget * widget) override + { + qobject_cast(widget)->loadSettings(); + } + + void saveSettings(QWidget * widget) override + { + qobject_cast(widget)->saveSettings(); + if (HttpSettings::isEnabled()) + m_service->start(); + else + m_service->stop(); + } +private: + Service *m_service; }; #endif @@ -510,7 +523,7 @@ void MainWindow::updateWindowTitle() void MainWindow::showAboutDialog() { AboutDialog* aboutDialog = new AboutDialog(this); - aboutDialog->show(); + aboutDialog->open(); } void MainWindow::switchToDatabases() diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp index 5696ff121..3ec9674fe 100644 --- a/src/gui/SettingsWidget.cpp +++ b/src/gui/SettingsWidget.cpp @@ -22,6 +22,7 @@ #include "autotype/AutoType.h" #include "core/Config.h" #include "core/Translator.h" +#include "core/FilePath.h" class SettingsWidget::ExtraPage { @@ -57,16 +58,16 @@ SettingsWidget::SettingsWidget(QWidget* parent) m_secUi->setupUi(m_secWidget); m_generalUi->setupUi(m_generalWidget); - add(tr("General"), m_generalWidget); - add(tr("Security"), m_secWidget); + addPage(tr("General"), FilePath::instance()->icon("categories", "preferences-other"), m_generalWidget); + addPage(tr("Security"), FilePath::instance()->icon("status", "security-high"), m_secWidget); + + if (!autoType()->isAvailable()) { + m_generalUi->generalSettingsTabWidget->removeTab(1); + } - m_generalUi->autoTypeShortcutWidget->setVisible(autoType()->isAvailable()); - m_generalUi->autoTypeShortcutLabel->setVisible(autoType()->isAvailable()); #ifdef Q_OS_MAC // systray not useful on OS X - m_generalUi->systrayShowCheckBox->setVisible(false); - m_generalUi->systrayMinimizeOnCloseCheckBox->setVisible(false); - m_generalUi->systrayMinimizeToTrayCheckBox->setVisible(false); + m_generalUi->systraySettings->setVisible(false); #endif connect(this, SIGNAL(accepted()), SLOT(saveSettings())); @@ -87,12 +88,12 @@ SettingsWidget::~SettingsWidget() { } -void SettingsWidget::addSettingsPage(ISettingsPage *page) +void SettingsWidget::addSettingsPage(ISettingsPage* page) { - QWidget * widget = page->createWidget(); + QWidget* widget = page->createWidget(); widget->setParent(this); m_extraPages.append(ExtraPage(page, widget)); - add(page->name(), widget); + addPage(page->name(), page->icon(), widget); } void SettingsWidget::loadSettings() @@ -122,6 +123,7 @@ void SettingsWidget::loadSettings() m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool()); m_generalUi->systrayMinimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool()); m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get("GUI/MinimizeOnStartup").toBool()); + m_generalUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool()); if (autoType()->isAvailable()) { m_globalAutoTypeKey = static_cast(config()->get("GlobalAutoTypeKey").toInt()); @@ -141,12 +143,11 @@ void SettingsWidget::loadSettings() m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool()); m_secUi->passwordRepeatCheckBox->setChecked(config()->get("security/passwordsrepeat").toBool()); - m_secUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool()); Q_FOREACH (const ExtraPage& page, m_extraPages) page.loadSettings(); - setCurrentRow(0); + setCurrentPage(0); } void SettingsWidget::saveSettings() @@ -172,6 +173,8 @@ void SettingsWidget::saveSettings() config()->set("GUI/MinimizeOnClose", m_generalUi->systrayMinimizeOnCloseCheckBox->isChecked()); config()->set("GUI/MinimizeOnStartup", m_generalUi->systrayMinimizeOnStartup->isChecked()); + config()->set("security/autotypeask", m_generalUi->autoTypeAskCheckBox->isChecked()); + if (autoType()->isAvailable()) { config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key()); config()->set("GlobalAutoTypeModifiers", @@ -187,8 +190,6 @@ void SettingsWidget::saveSettings() config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked()); config()->set("security/passwordsrepeat", m_secUi->passwordRepeatCheckBox->isChecked()); - config()->set("security/autotypeask", m_secUi->autoTypeAskCheckBox->isChecked()); - Q_FOREACH (const ExtraPage& page, m_extraPages) page.saveSettings(); diff --git a/src/gui/SettingsWidget.h b/src/gui/SettingsWidget.h index 236206299..e94f48767 100644 --- a/src/gui/SettingsWidget.h +++ b/src/gui/SettingsWidget.h @@ -29,6 +29,7 @@ class ISettingsPage { public: virtual ~ISettingsPage() {} virtual QString name() = 0; + virtual QIcon icon() = 0; virtual QWidget * createWidget() = 0; virtual void loadSettings(QWidget * widget) = 0; virtual void saveSettings(QWidget * widget) = 0; diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui index eb9209777..88d7cad45 100644 --- a/src/gui/SettingsWidgetGeneral.ui +++ b/src/gui/SettingsWidgetGeneral.ui @@ -7,187 +7,357 @@ 0 0 684 - 452 + 732 - - - QFormLayout::AllNonFixedFieldsGrow + + + 0 - - - - Remember last databases - - - true - - - - - - - Remember last key files - - - true - - - - - - - Load previous databases on startup - - - - - - - Automatically save on exit - - - - - - - Automatically save after every change - - - - - - - Automatically reload the database when modified externally - - - - - - - Minimize when copying to clipboard - - - - - - - Use group icon on entry creation - - - - - - - Global Auto-Type shortcut - - - - - - - - - - Use entry title to match windows for global auto-type - - - - - - - Language - - - - - - - - - - QLayout::SetMaximumSize - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 0 - 0 - - - - Hide window to system tray when minimized - - - - - - - - - QLayout::SetMaximumSize - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Hide window to system tray instead of app exit - - - - - - - - - QLayout::SetMaximumSize - - - - - Minimize window at application startup - - - - - - - - - Show a system tray icon + + 0 + + + 0 + + + 0 + + + + + 0 + + + Basic Settings + + + + + + Remember last databases + + + true + + + + + + + Remember last key files and security dongles + + + true + + + + + + + Load previous databases on startup + + + + + + + Automatically save on exit + + + + + + + Automatically save after every change + + + + + + + Automatically reload the database when modified externally + + + + + + + Minimize when copying to clipboard + + + + + + + Minimize window at application startup + + + + + + + Use group icon on entry creation + + + true + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 30 + + + + + + + + Show a system tray icon + + + + + + + 0 + + + QLayout::SetMaximumSize + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + false + + + + 0 + 0 + + + + Hide window to system tray when minimized + + + + + + + + + 0 + + + QLayout::SetMaximumSize + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + false + + + Hide window to system tray instead of app exit + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 30 + + + + + + + + 15 + + + + + + 0 + 0 + + + + Language + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + + Auto-Type + + + + + + Use entry title to match windows for global Auto-Type + + + + + + + Always ask before performing Auto-Type + + + true + + + + + + + 15 + + + + + + 0 + 0 + + + + Global Auto-Type shortcut + + + Qt::AlignLeading + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + @@ -199,15 +369,6 @@
autotype/ShortcutWidget.h
- - rememberLastDatabasesCheckBox - rememberLastKeyFilesCheckBox - openPreviousDatabasesOnStartupCheckBox - autoSaveOnExitCheckBox - autoSaveAfterEveryChangeCheckBox - minimizeOnCopyCheckBox - autoTypeShortcutWidget - diff --git a/src/gui/SettingsWidgetSecurity.ui b/src/gui/SettingsWidgetSecurity.ui index d664736ae..08fa6f4ea 100644 --- a/src/gui/SettingsWidgetSecurity.ui +++ b/src/gui/SettingsWidgetSecurity.ui @@ -6,91 +6,144 @@ 0 0 - 374 - 303 + 595 + 443
- - - - - Clear clipboard after + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Timeouts + + + + + false + + + + 0 + 0 + + + + sec + + + 1 + + + 999 + + + 10 + + + + + + + false + + + + 0 + 0 + + + + sec + + + 10 + + + 9999 + + + 240 + + + + + + + Clear clipboard after + + + + + + + Lock databases after inactivity of + + + + - - - - false - - - sec - - - 1 - - - 999 + + + + Convenience + + + + + Don't require password repeat when it is visible + + + + + + + Show passwords in cleartext by default + + + + + + + Lock databases after minimizing the window + + + + - - - - Lock databases after inactivity of + + + + Qt::Vertical - - - - - - false + + QSizePolicy::Expanding - - sec + + + 20 + 30 + - - 10 - - - 9999 - - - - - - - Lock databases after minimizing the window - - - - - - - Show passwords in cleartext by default - - - - - - - Don't require password repeat when it is visible - - - - - - - Always ask before performing auto-type - - + - - clearClipboardCheckBox - clearClipboardSpinBox - diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 4acfd8765..51e0bb735 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -90,7 +90,7 @@ EditEntryWidget::~EditEntryWidget() void EditEntryWidget::setupMain() { m_mainUi->setupUi(m_mainWidget); - add(tr("Entry"), m_mainWidget); + addPage(tr("Entry"), FilePath::instance()->icon("actions", "document-edit"), m_mainWidget); m_mainUi->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show")); m_mainUi->togglePasswordGeneratorButton->setIcon(filePath()->icon("actions", "password-generator", false)); @@ -115,7 +115,7 @@ void EditEntryWidget::setupMain() void EditEntryWidget::setupAdvanced() { m_advancedUi->setupUi(m_advancedWidget); - add(tr("Advanced"), m_advancedWidget); + addPage(tr("Advanced"), FilePath::instance()->icon("categories", "preferences-other"), m_advancedWidget); m_attachmentsModel->setEntryAttachments(m_entryAttachments); m_advancedUi->attachmentsView->setModel(m_attachmentsModel); @@ -139,13 +139,13 @@ void EditEntryWidget::setupAdvanced() void EditEntryWidget::setupIcon() { - add(tr("Icon"), m_iconsWidget); + addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_iconsWidget); } void EditEntryWidget::setupAutoType() { m_autoTypeUi->setupUi(m_autoTypeWidget); - add(tr("Auto-Type"), m_autoTypeWidget); + addPage(tr("Auto-Type"), FilePath::instance()->icon("actions", "key-enter"), m_autoTypeWidget); m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->inheritSequenceButton); m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->customSequenceButton); @@ -177,13 +177,13 @@ void EditEntryWidget::setupAutoType() void EditEntryWidget::setupProperties() { - add(tr("Properties"), m_editWidgetProperties); + addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties); } void EditEntryWidget::setupHistory() { m_historyUi->setupUi(m_historyWidget); - add(tr("History"), m_historyWidget); + addPage(tr("History"), FilePath::instance()->icon("actions", "view-history"), m_historyWidget); m_sortModel->setSourceModel(m_historyModel); m_sortModel->setDynamicSortFilter(true); @@ -291,8 +291,8 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, bool history, const Q setForms(entry); setReadOnly(m_history); - setCurrentRow(0); - setRowHidden(m_historyWidget, m_history); + setCurrentPage(0); + setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1); } void EditEntryWidget::setForms(const Entry* entry, bool restore) diff --git a/src/gui/entry/EditEntryWidgetAutoType.ui b/src/gui/entry/EditEntryWidgetAutoType.ui index c1f243680..21e102bfe 100644 --- a/src/gui/entry/EditEntryWidgetAutoType.ui +++ b/src/gui/entry/EditEntryWidgetAutoType.ui @@ -88,167 +88,183 @@
- - - - - - - false - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 0 - 0 - - - - - 0 - 25 - - - - + - - - - - - - false - - - - 0 - 0 - - - - - 0 - 25 - - - - - - - - - - - - - - - - - - Window title: - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 1 - 10 - - - - - - - - Use default se&quence - - - - - - - Set custo&m sequence: - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 1 - - - - - - - - false - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + + + Window Associations + + + + + + + + false + + + true + + + false + + + false + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 25 + + + + + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 25 + + + + - + + + + + + + + + + + + + Window title: + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 1 + 10 + + + + + + + + Use default se&quence + + + + + + + Set custo&m sequence: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 1 + + + + + + + + false + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + +
diff --git a/src/gui/entry/EditEntryWidgetHistory.ui b/src/gui/entry/EditEntryWidgetHistory.ui index 2ee8e08f3..8390f22fa 100644 --- a/src/gui/entry/EditEntryWidgetHistory.ui +++ b/src/gui/entry/EditEntryWidgetHistory.ui @@ -25,9 +25,15 @@ + + true + true + + 160 + diff --git a/src/gui/entry/EditEntryWidget_p.h b/src/gui/entry/EditEntryWidget_p.h index cdae8bd3d..0e37c1fe8 100644 --- a/src/gui/entry/EditEntryWidget_p.h +++ b/src/gui/entry/EditEntryWidget_p.h @@ -18,46 +18,8 @@ #ifndef KEEPASSX_EDITENTRYWIDGET_P_H #define KEEPASSX_EDITENTRYWIDGET_P_H -#include +#include #include -#include -#include - -class CategoryListViewDelegate : public QStyledItemDelegate -{ -public: - explicit CategoryListViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {} - - QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const - { - QSize size = QStyledItemDelegate::sizeHint(option, index); - size.setHeight(qMax(size.height(), 22)); - return size; - } -}; - -class CategoryListWidget : public QListWidget -{ -public: - explicit CategoryListWidget(QWidget* parent = 0) : QListWidget(parent) - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); - setItemDelegate(new CategoryListViewDelegate(this)); - } - - virtual QSize sizeHint() const - { - QSize sizeHint = QListWidget::sizeHint(); - - int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; - if (verticalScrollBar()->isVisible()) { - width += verticalScrollBar()->width(); - } - sizeHint.setWidth(width); - - return sizeHint; - } -}; class AttributesListView : public QListView { @@ -65,14 +27,13 @@ public: explicit AttributesListView(QWidget* parent = 0) : QListView(parent) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - setItemDelegate(new CategoryListViewDelegate(this)); } - virtual QSize sizeHint() const + QSize sizeHint() const override { QSize sizeHint = QListView::sizeHint(); - int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; + int width = sizeHintForColumn(0) + frameWidth() * 2; if (verticalScrollBar()->isVisible()) { width += verticalScrollBar()->width(); } diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp index 5b9dfcbc8..ac4e4ce99 100644 --- a/src/gui/group/EditGroupWidget.cpp +++ b/src/gui/group/EditGroupWidget.cpp @@ -19,6 +19,7 @@ #include "ui_EditGroupWidgetMain.h" #include "core/Metadata.h" +#include "core/FilePath.h" #include "gui/EditWidgetIcons.h" #include "gui/EditWidgetProperties.h" @@ -33,9 +34,9 @@ EditGroupWidget::EditGroupWidget(QWidget* parent) { m_mainUi->setupUi(m_editGroupWidgetMain); - add(tr("Group"), m_editGroupWidgetMain); - add(tr("Icon"), m_editGroupWidgetIcons); - add(tr("Properties"), m_editWidgetProperties); + addPage(tr("Group"), FilePath::instance()->icon("actions", "document-edit"), m_editGroupWidgetMain); + addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_editGroupWidgetIcons); + addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties); connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool))); connect(m_mainUi->autoTypeSequenceCustomRadio, SIGNAL(toggled(bool)), @@ -94,7 +95,7 @@ void EditGroupWidget::loadGroup(Group* group, bool create, Database* database) m_editWidgetProperties->setFields(group->timeInfo(), group->uuid()); - setCurrentRow(0); + setCurrentPage(0); m_mainUi->editName->setFocus(); } diff --git a/src/gui/group/EditGroupWidgetMain.ui b/src/gui/group/EditGroupWidgetMain.ui index b8abf762c..20ce2f414 100644 --- a/src/gui/group/EditGroupWidgetMain.ui +++ b/src/gui/group/EditGroupWidgetMain.ui @@ -6,116 +6,147 @@ 0 0 - 676 - 356 + 579 + 407 - - - - - QFormLayout::ExpandingFieldsGrow + + + 10 + + + 0 + + + 0 + + + 0 + + + + + Name - - - - Name + + + + + + + + + Notes + + + + + + + + 0 + 0 + + + + + 16777215 + 120 + + + + + + + + Expires + + + + + + + + + + false + + + true + + + + + + + Search + + + + + + + + + + Auto-Type + + + + + + + &Use default Auto-Type sequence of parent group + + + + + + + Set default Auto-Type se&quence + + + + + + + + + Qt::Horizontal - - - - - - - - - Notes + + QSizePolicy::Fixed - - - - - - - - - Expires + + + 13 + 1 + - + - - + + false - - true - - - - - Search - - - - - - - - - - Auto-type - - - - - - - - - - Use default auto-type sequence of parent group - - - - - - - Set default auto-type sequence - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 1 - - - - - - - - false - - - - - + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/src/http/HttpPasswordGeneratorWidget.cpp b/src/http/HttpPasswordGeneratorWidget.cpp index 30e4f71e7..031ff30ad 100644 --- a/src/http/HttpPasswordGeneratorWidget.cpp +++ b/src/http/HttpPasswordGeneratorWidget.cpp @@ -32,13 +32,10 @@ HttpPasswordGeneratorWidget::HttpPasswordGeneratorWidget(QWidget* parent) { m_ui->setupUi(this); - connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(saveSettings())); - connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(sliderMoved())); connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(spinBoxChanged())); connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator())); - m_ui->buttonApply->setEnabled(true); loadSettings(); reset(); diff --git a/src/http/HttpPasswordGeneratorWidget.h b/src/http/HttpPasswordGeneratorWidget.h index 2b2ace39b..f8e35c232 100644 --- a/src/http/HttpPasswordGeneratorWidget.h +++ b/src/http/HttpPasswordGeneratorWidget.h @@ -35,10 +35,10 @@ public: explicit HttpPasswordGeneratorWidget(QWidget* parent = nullptr); ~HttpPasswordGeneratorWidget(); void loadSettings(); + void saveSettings(); void reset(); private Q_SLOTS: - void saveSettings(); void sliderMoved(); void spinBoxChanged(); diff --git a/src/http/HttpPasswordGeneratorWidget.ui b/src/http/HttpPasswordGeneratorWidget.ui index 29399bcd6..066b9c512 100644 --- a/src/http/HttpPasswordGeneratorWidget.ui +++ b/src/http/HttpPasswordGeneratorWidget.ui @@ -6,14 +6,26 @@ 0 0 - 434 - 250 + 500 + 181 + + 0 + + + 0 + + + 0 + + + 0 + @@ -168,42 +180,8 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Accept - - - - - - - - PasswordComboBox - QComboBox -
gui/PasswordComboBox.h
-
-
sliderLength spinBoxLength @@ -213,7 +191,6 @@ checkBoxSpecialChars checkBoxExcludeAlike checkBoxEnsureEvery - buttonApply diff --git a/src/http/OptionDialog.cpp b/src/http/OptionDialog.cpp index 5245d333b..fd30f8745 100644 --- a/src/http/OptionDialog.cpp +++ b/src/http/OptionDialog.cpp @@ -15,15 +15,24 @@ #include "ui_OptionDialog.h" #include "HttpSettings.h" +#include "core/FilePath.h" + #include OptionDialog::OptionDialog(QWidget *parent) : QWidget(parent), - ui(new Ui::OptionDialog()) + m_ui(new Ui::OptionDialog()) { - ui->setupUi(this); - connect(ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys())); - connect(ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions())); + m_ui->setupUi(this); + connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys())); + connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions())); + + m_ui->warningWidget->showMessage(tr("The following options can be dangerous!\nChange them only if you know what you are doing."), MessageWidget::Warning); + m_ui->warningWidget->setIcon(FilePath::instance()->icon("status", "dialog-warning")); + m_ui->warningWidget->setCloseButtonVisible(false); + + m_ui->tabWidget->setEnabled(m_ui->enableHttpServer->isChecked()); + connect(m_ui->enableHttpServer, SIGNAL(toggled(bool)), m_ui->tabWidget, SLOT(setEnabled(bool))); } OptionDialog::~OptionDialog() @@ -33,65 +42,48 @@ OptionDialog::~OptionDialog() void OptionDialog::loadSettings() { HttpSettings settings; - ui->enableHttpServer->setChecked(settings.isEnabled()); + m_ui->enableHttpServer->setChecked(settings.isEnabled()); - ui->showNotification->setChecked(settings.showNotification()); - ui->bestMatchOnly->setChecked(settings.bestMatchOnly()); - ui->unlockDatabase->setChecked(settings.unlockDatabase()); - ui->matchUrlScheme->setChecked(settings.matchUrlScheme()); + m_ui->showNotification->setChecked(settings.showNotification()); + m_ui->bestMatchOnly->setChecked(settings.bestMatchOnly()); + m_ui->unlockDatabase->setChecked(settings.unlockDatabase()); + m_ui->matchUrlScheme->setChecked(settings.matchUrlScheme()); if (settings.sortByUsername()) - ui->sortByUsername->setChecked(true); + m_ui->sortByUsername->setChecked(true); else - ui->sortByTitle->setChecked(true); - ui->httpPort->setText(QString::number(settings.httpPort())); + m_ui->sortByTitle->setChecked(true); + m_ui->httpPort->setText(QString::number(settings.httpPort())); -/* - ui->checkBoxLower->setChecked(settings.passwordUseLowercase()); - ui->checkBoxNumbers->setChecked(settings.passwordUseNumbers()); - ui->checkBoxUpper->setChecked(settings.passwordUseUppercase()); - ui->checkBoxSpecialChars->setChecked(settings.passwordUseSpecial()); - ui->checkBoxEnsureEvery->setChecked(settings.passwordEveryGroup()); - ui->checkBoxExcludeAlike->setChecked(settings.passwordExcludeAlike()); - ui->spinBoxLength->setValue(settings.passwordLength()); -*/ + m_ui->alwaysAllowAccess->setChecked(settings.alwaysAllowAccess()); + m_ui->alwaysAllowUpdate->setChecked(settings.alwaysAllowUpdate()); + m_ui->searchInAllDatabases->setChecked(settings.searchInAllDatabases()); + m_ui->supportKphFields->setChecked(settings.supportKphFields()); - ui->alwaysAllowAccess->setChecked(settings.alwaysAllowAccess()); - ui->alwaysAllowUpdate->setChecked(settings.alwaysAllowUpdate()); - ui->searchInAllDatabases->setChecked(settings.searchInAllDatabases()); - ui->supportKphFields->setChecked(settings.supportKphFields()); + m_ui->passwordGenerator->loadSettings(); } void OptionDialog::saveSettings() { HttpSettings settings; - settings.setEnabled(ui->enableHttpServer->isChecked()); + settings.setEnabled(m_ui->enableHttpServer->isChecked()); - settings.setShowNotification(ui->showNotification->isChecked()); - settings.setBestMatchOnly(ui->bestMatchOnly->isChecked()); - settings.setUnlockDatabase(ui->unlockDatabase->isChecked()); - settings.setMatchUrlScheme(ui->matchUrlScheme->isChecked()); - settings.setSortByUsername(ui->sortByUsername->isChecked()); + settings.setShowNotification(m_ui->showNotification->isChecked()); + settings.setBestMatchOnly(m_ui->bestMatchOnly->isChecked()); + settings.setUnlockDatabase(m_ui->unlockDatabase->isChecked()); + settings.setMatchUrlScheme(m_ui->matchUrlScheme->isChecked()); + settings.setSortByUsername(m_ui->sortByUsername->isChecked()); - int port = ui->httpPort->text().toInt(); + int port = m_ui->httpPort->text().toInt(); if (port < 1024) { QMessageBox::warning(this, tr("Cannot bind to privileged ports"), tr("Cannot bind to privileged ports below 1024!\nUsing default port 19455.")); port = 19455; } settings.setHttpPort(port); + settings.setAlwaysAllowAccess(m_ui->alwaysAllowAccess->isChecked()); + settings.setAlwaysAllowUpdate(m_ui->alwaysAllowUpdate->isChecked()); + settings.setSearchInAllDatabases(m_ui->searchInAllDatabases->isChecked()); + settings.setSupportKphFields(m_ui->supportKphFields->isChecked()); -/* - settings.setPasswordUseLowercase(ui->checkBoxLower->isChecked()); - settings.setPasswordUseNumbers(ui->checkBoxNumbers->isChecked()); - settings.setPasswordUseUppercase(ui->checkBoxUpper->isChecked()); - settings.setPasswordUseSpecial(ui->checkBoxSpecialChars->isChecked()); - settings.setPasswordEveryGroup(ui->checkBoxEnsureEvery->isChecked()); - settings.setPasswordExcludeAlike(ui->checkBoxExcludeAlike->isChecked()); - settings.setPasswordLength(ui->spinBoxLength->value()); -*/ - - settings.setAlwaysAllowAccess(ui->alwaysAllowAccess->isChecked()); - settings.setAlwaysAllowUpdate(ui->alwaysAllowUpdate->isChecked()); - settings.setSearchInAllDatabases(ui->searchInAllDatabases->isChecked()); - settings.setSupportKphFields(ui->supportKphFields->isChecked()); + m_ui->passwordGenerator->saveSettings(); } diff --git a/src/http/OptionDialog.h b/src/http/OptionDialog.h index adec9f695..1b1819159 100644 --- a/src/http/OptionDialog.h +++ b/src/http/OptionDialog.h @@ -38,7 +38,7 @@ Q_SIGNALS: void removeStoredPermissions(); private: - QScopedPointer ui; + QScopedPointer m_ui; }; #endif // OPTIONDIALOG_H diff --git a/src/http/OptionDialog.ui b/src/http/OptionDialog.ui index c9aae49ef..abe994772 100644 --- a/src/http/OptionDialog.ui +++ b/src/http/OptionDialog.ui @@ -6,27 +6,38 @@ 0 0 - 605 - 429 + 577 + 404 Dialog + + 0 + + + 0 + + + 0 + + + 0 + + + This is required for accessing your databases from ChromeIPass or PassIFox + - Enable KeepassXC HTTP protocol -This is required for accessing your databases from ChromeIPass or PassIFox + Enable KeePassHTTP server - - QTabWidget::Rounded - 0 @@ -40,13 +51,18 @@ This is required for accessing your databases from ChromeIPass or PassIFox Sh&ow a notification when credentials are requested + + true + + + Only returns the best matches for a specific URL instead of all entries for the whole domain. + - &Return only best matching entries for a URL instead -of all entries for the whole domain + &Return only best matching entries @@ -55,13 +71,18 @@ of all entries for the whole domain Re&quest to unlock the database if it is locked + + true +
+ + Only entries with the same scheme (http://, https://, ftp://, ...) are returned. + - &Match URL schemes -Only entries with the same scheme (http://, https://, ftp://, ...) are returned + &Match URL schemes @@ -110,7 +131,7 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned< - Password generator + Password Generator @@ -135,20 +156,14 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned< Advanced - + - - - - 75 - true - - - - color: rgb(255, 0, 0); - - - The following options can be dangerous. Change them only if you know what you are doing. + + + + 0 + 0 + @@ -168,35 +183,21 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned< + + Only the selected database has to be connected with a client. + Searc&h in all opened databases for matching entries - - - - Only the selected database has to be connected with a client! - - - 30 - - - - - &Return advanced string fields which start with "KPH: " - - - - - - + Automatically creating or updating string fields is not supported. - - 30 + + &Return advanced string fields which start with "KPH: " @@ -217,25 +218,8 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned< - - - - - d0000 - - - Default port: 19455 - - - - - - - KeePassXC will listen to this port on 127.0.0.1 - - - - + + @@ -251,6 +235,29 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned< + + + + + 0 + 0 + + + + d0000 + + + Default port: 19455 + + + + + + + KeePassXC will listen to this port on 127.0.0.1 + + + @@ -279,6 +286,12 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
http/HttpPasswordGeneratorWidget.h
1 + + MessageWidget + QWidget +
gui/MessageWidget.h
+ 1 +