Merge pull request #340 from keepassxreboot/feature/rework-settings

User interface rework of settings and "About" dialog
This commit is contained in:
Janek Bevendorff 2017-02-25 01:08:45 +01:00 committed by GitHub
commit 0b48e68a3c
46 changed files with 1724 additions and 872 deletions

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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
@ -132,6 +133,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

View File

@ -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);

View File

@ -23,15 +23,21 @@
#include "core/FilePath.h"
#include "crypto/Crypto.h"
#include <QClipboard>
#include <QSysInfo>
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());
}

View File

@ -33,6 +33,9 @@ public:
explicit AboutDialog(QWidget* parent = nullptr);
~AboutDialog();
protected slots:
void copyToClipboard();
private:
QScopedPointer<Ui::AboutDialog> m_ui;
};

View File

@ -6,20 +6,23 @@
<rect>
<x>0</x>
<y>0</y>
<width>455</width>
<height>266</height>
<width>479</width>
<height>478</height>
</rect>
</property>
<property name="windowTitle">
<string>About KeePassXC</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<property name="topMargin">
<number>15</number>
</property>
<property name="bottomMargin">
<number>20</number>
</property>
<item alignment="Qt::AlignVCenter">
<widget class="QLabel" name="iconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -27,9 +30,21 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item>
<item alignment="Qt::AlignVCenter">
<widget class="QLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -37,6 +52,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true"> KeePassXC</string>
</property>
@ -45,66 +66,161 @@
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">&lt;a href=&quot;https://keepassxc.org/&quot;&gt;https://keepassxc.org/&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_git">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_libs">
<property name="text">
<string>Using:</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_features">
<property name="text">
<string>Extensions:
</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>About</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">&lt;p&gt;Website: &lt;a href=&quot;https://keepassxc.org/&quot;&gt;https://keepassxc.org/&lt;/a&gt;&lt;/p&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;https://github.com/&lt;/a&gt;&lt;/p&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;p&gt;Main contributors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;debfx (KeePassX)&lt;/li&gt;
&lt;li&gt;droidmonkey&lt;/li&gt;
&lt;li&gt;louib&lt;/li&gt;
&lt;li&gt;phoerious&lt;li&gt;
&lt;li&gt;thezero&lt;/li&gt;
&lt;/ul&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Debug Info</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Include the following information whenever you report a bug:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="debugInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyToClipboard">
<property name="text">
<string>Copy to clipboard</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "CategoryListWidget.h"
#include "ui_CategoryListWidget.h"
#include <QListWidget>
#include <QScrollBar>
#include <QSize>
#include <QStyledItemDelegate>
#include <QPainter>
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 <QProxyStyle>
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<float>(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<QStyle> 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());
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QWidget>
#include <QStyledItemDelegate>
#include <QPointer>
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<CategoryListWidgetDelegate> m_itemDelegate;
const QScopedPointer<Ui::CategoryListWidget> 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<QListWidget> m_listWidget;
QSize m_size;
Q_DISABLE_COPY(CategoryListWidgetDelegate)
};

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CategoryListWidget</class>
<widget class="QWidget" name="CategoryListWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>182</width>
<height>418</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="scrollUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>15</height>
</size>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="arrowType">
<enum>Qt::UpArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="categoryList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="flow">
<enum>QListView::TopToBottom</enum>
</property>
<property name="isWrapping" stdset="0">
<bool>false</bool>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="scrollDown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>15</height>
</size>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>categoryList</tabstop>
<tabstop>scrollUp</tabstop>
<tabstop>scrollDown</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -287,7 +287,7 @@ void DatabaseWidget::createEntry()
void DatabaseWidget::setIconFromParent()
{
if (!config()->get("UseGroupIconOnEntryCreation").toBool()) {
if (!config()->get("UseGroupIconOnEntryCreation", true).toBool()) {
return;
}

View File

@ -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)

View File

@ -19,6 +19,8 @@
#define KEEPASSX_EDITWIDGET_H
#include <QScopedPointer>
#include <QtWidgets/QStyledItemDelegate>
#include <QStyledItemDelegate>
#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();

View File

@ -38,9 +38,16 @@
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
<widget class="CategoryListWidget" name="categoryList"/>
<widget class="CategoryListWidget" name="categoryList" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
@ -52,7 +59,7 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>5</number>
</property>
@ -76,13 +83,11 @@
</customwidget>
<customwidget>
<class>CategoryListWidget</class>
<extends>QListWidget</extends>
<header>gui/entry/EditEntryWidget_p.h</header>
<extends>QWidget</extends>
<header>gui/CategoryListWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>categoryList</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -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)

View File

@ -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<OptionDialog*>(widget)->loadSettings();
}
virtual void saveSettings(QWidget * widget) {
qobject_cast<OptionDialog*>(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<OptionDialog*>(widget)->loadSettings();
}
void saveSettings(QWidget * widget) override
{
qobject_cast<OptionDialog*>(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()

View File

@ -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<Qt::Key>(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();

View File

@ -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;

View File

@ -7,187 +7,357 @@
<x>0</x>
<y>0</y>
<width>684</width>
<height>452</height>
<height>732</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
<property name="text">
<string>Remember last databases</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="rememberLastKeyFilesCheckBox">
<property name="text">
<string>Remember last key files</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
<property name="text">
<string>Load previous databases on startup</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="autoSaveOnExitCheckBox">
<property name="text">
<string>Automatically save on exit</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
<property name="text">
<string>Automatically save after every change</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="autoReloadOnChangeCheckBox">
<property name="text">
<string>Automatically reload the database when modified externally</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="minimizeOnCopyCheckBox">
<property name="text">
<string>Minimize when copying to clipboard</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
<property name="text">
<string>Use group icon on entry creation</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="autoTypeShortcutLabel">
<property name="text">
<string>Global Auto-Type shortcut</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
<property name="text">
<string>Use entry title to match windows for global auto-type</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="languageLabel">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QComboBox" name="languageComboBox"/>
</item>
<item row="12" column="0">
<layout class="QHBoxLayout" name="systray1Layout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Hide window to system tray when minimized</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="13" column="0">
<layout class="QHBoxLayout" name="systray2Layout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="systrayMinimizeOnCloseCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Hide window to system tray instead of app exit</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="14" column="0">
<layout class="QHBoxLayout" name="systray3Layout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QCheckBox" name="systrayMinimizeOnStartup">
<property name="text">
<string>Minimize window at application startup</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="systrayShowCheckBox">
<property name="text">
<string>Show a system tray icon</string>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="generalSettingsTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
<string>Basic Settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
<property name="text">
<string>Remember last databases</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="rememberLastKeyFilesCheckBox">
<property name="text">
<string>Remember last key files and security dongles</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
<property name="text">
<string>Load previous databases on startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoSaveOnExitCheckBox">
<property name="text">
<string>Automatically save on exit</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
<property name="text">
<string>Automatically save after every change</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoReloadOnChangeCheckBox">
<property name="text">
<string>Automatically reload the database when modified externally</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="minimizeOnCopyCheckBox">
<property name="text">
<string>Minimize when copying to clipboard</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="systrayMinimizeOnStartup">
<property name="text">
<string>Minimize window at application startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
<property name="text">
<string>Use group icon on entry creation</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="systraySettings" native="true">
<layout class="QVBoxLayout" name="systrayLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="systrayShowCheckBox">
<property name="text">
<string>Show a system tray icon</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Hide window to system tray when minimized</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="systrayMinimizeOnCloseCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Hide window to system tray instead of app exit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="trayIconSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="languageLabelLayout_2">
<property name="spacing">
<number>15</number>
</property>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="languageLabel_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="languageComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabAutotype">
<attribute name="title">
<string>Auto-Type</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
<property name="text">
<string>Use entry title to match windows for global Auto-Type</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoTypeAskCheckBox">
<property name="text">
<string>Always ask before performing Auto-Type</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>15</number>
</property>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="autoTypeShortcutLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Global Auto-Type shortcut</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading</set>
</property>
</widget>
</item>
<item>
<widget class="ShortcutWidget" name="autoTypeShortcutWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -199,15 +369,6 @@
<header>autotype/ShortcutWidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>rememberLastDatabasesCheckBox</tabstop>
<tabstop>rememberLastKeyFilesCheckBox</tabstop>
<tabstop>openPreviousDatabasesOnStartupCheckBox</tabstop>
<tabstop>autoSaveOnExitCheckBox</tabstop>
<tabstop>autoSaveAfterEveryChangeCheckBox</tabstop>
<tabstop>minimizeOnCopyCheckBox</tabstop>
<tabstop>autoTypeShortcutWidget</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -6,91 +6,144 @@
<rect>
<x>0</x>
<y>0</y>
<width>374</width>
<height>303</height>
<width>595</width>
<height>443</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="clearClipboardCheckBox">
<property name="text">
<string>Clear clipboard after</string>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Timeouts</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QSpinBox" name="clearClipboardSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="lockDatabaseIdleSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="value">
<number>240</number>
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QCheckBox" name="clearClipboardCheckBox">
<property name="text">
<string>Clear clipboard after</string>
</property>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QCheckBox" name="lockDatabaseIdleCheckBox">
<property name="text">
<string>Lock databases after inactivity of</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="clearClipboardSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Convenience</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="passwordRepeatCheckBox">
<property name="text">
<string>Don't require password repeat when it is visible</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="passwordCleartextCheckBox">
<property name="text">
<string>Show passwords in cleartext by default</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lockDatabaseMinimizeCheckBox">
<property name="text">
<string>Lock databases after minimizing the window</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="lockDatabaseIdleCheckBox">
<property name="text">
<string>Lock databases after inactivity of</string>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="lockDatabaseIdleSpinBox">
<property name="enabled">
<bool>false</bool>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="suffix">
<string> sec</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>30</height>
</size>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="lockDatabaseMinimizeCheckBox">
<property name="text">
<string>Lock databases after minimizing the window</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="passwordCleartextCheckBox">
<property name="text">
<string>Show passwords in cleartext by default</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="passwordRepeatCheckBox">
<property name="text">
<string>Don't require password repeat when it is visible</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="autoTypeAskCheckBox">
<property name="text">
<string>Always ask before performing auto-type</string>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>clearClipboardCheckBox</tabstop>
<tabstop>clearClipboardSpinBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -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)

View File

@ -88,167 +88,183 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTreeView" name="assocView">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="2,1,1">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="assocAddButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="assocRemoveButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="windowTitleLabel">
<property name="text">
<string>Window title:</string>
</property>
</widget>
</item>
<item>
<widget class="WindowSelectComboBox" name="windowTitleCombo"/>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="defaultWindowSequenceButton">
<property name="text">
<string>Use default se&amp;quence</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="customWindowSequenceButton">
<property name="text">
<string>Set custo&amp;m sequence:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="windowSequenceEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<widget class="QGroupBox" name="windowsBox">
<property name="title">
<string>Window Associations</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTreeView" name="assocView">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="2,1,1">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="assocAddButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="assocRemoveButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="windowTitleLabel">
<property name="text">
<string>Window title:</string>
</property>
</widget>
</item>
<item>
<widget class="WindowSelectComboBox" name="windowTitleCombo"/>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="defaultWindowSequenceButton">
<property name="text">
<string>Use default se&amp;quence</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="customWindowSequenceButton">
<property name="text">
<string>Set custo&amp;m sequence:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="windowSequenceEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<zorder></zorder>
<zorder></zorder>
<zorder></zorder>
<zorder></zorder>
<zorder></zorder>
</widget>
</item>
</layout>
</widget>

View File

@ -25,9 +25,15 @@
</property>
<item>
<widget class="QTreeView" name="historyView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="headerDefaultSectionSize">
<number>160</number>
</attribute>
</widget>
</item>
<item>

View File

@ -18,46 +18,8 @@
#ifndef KEEPASSX_EDITENTRYWIDGET_P_H
#define KEEPASSX_EDITENTRYWIDGET_P_H
#include <QListWidget>
#include <QListView>
#include <QScrollBar>
#include <QSize>
#include <QStyledItemDelegate>
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();
}

View File

@ -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();
}

View File

@ -6,116 +6,147 @@
<rect>
<x>0</x>
<y>0</y>
<width>676</width>
<height>356</height>
<width>579</width>
<height>407</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name</string>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="editName"/>
</item>
<item row="1" column="0" alignment="Qt::AlignRight|Qt::AlignTop">
<widget class="QLabel" name="labelNotes">
<property name="text">
<string>Notes</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="editNotes">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QCheckBox" name="expireCheck">
<property name="text">
<string>Expires</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="autotypeComboBox"/>
</item>
<item row="2" column="1">
<widget class="QDateTimeEdit" name="expireDatePicker">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="searchLabel">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="searchComboBox"/>
</item>
<item row="4" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="autotypeLabel">
<property name="text">
<string>Auto-Type</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="autoTypeSequenceInherit">
<property name="text">
<string>&amp;Use default Auto-Type sequence of parent group</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QRadioButton" name="autoTypeSequenceCustomRadio">
<property name="text">
<string>Set default Auto-Type se&amp;quence</string>
</property>
</widget>
</item>
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="editName"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelNotes">
<property name="text">
<string>Notes</string>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="editNotes"/>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="expireCheck">
<property name="text">
<string>Expires</string>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>1</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="2" column="1">
<widget class="QDateTimeEdit" name="expireDatePicker">
<item>
<widget class="QLineEdit" name="autoTypeSequenceCustomEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="searchLabel">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="searchComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="autotypeLabel">
<property name="text">
<string>Auto-type</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="autotypeComboBox"/>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="autoTypeSequenceInherit">
<property name="text">
<string>Use default auto-type sequence of parent group</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QRadioButton" name="autoTypeSequenceCustomRadio">
<property name="text">
<string>Set default auto-type sequence</string>
</property>
</widget>
</item>
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="autoTypeSequenceCustomEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>

View File

@ -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();

View File

@ -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();

View File

@ -6,14 +6,26 @@
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>250</height>
<width>500</width>
<height>181</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
@ -168,42 +180,8 @@
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonApply">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Accept</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>PasswordComboBox</class>
<extends>QComboBox</extends>
<header location="global">gui/PasswordComboBox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>sliderLength</tabstop>
<tabstop>spinBoxLength</tabstop>
@ -213,7 +191,6 @@
<tabstop>checkBoxSpecialChars</tabstop>
<tabstop>checkBoxExcludeAlike</tabstop>
<tabstop>checkBoxEnsureEvery</tabstop>
<tabstop>buttonApply</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -15,15 +15,24 @@
#include "ui_OptionDialog.h"
#include "HttpSettings.h"
#include "core/FilePath.h"
#include <QMessageBox>
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();
}

View File

@ -38,7 +38,7 @@ Q_SIGNALS:
void removeStoredPermissions();
private:
QScopedPointer<Ui::OptionDialog> ui;
QScopedPointer<Ui::OptionDialog> m_ui;
};
#endif // OPTIONDIALOG_H

View File

@ -6,27 +6,38 @@
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
<height>429</height>
<width>577</width>
<height>404</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="enableHttpServer">
<property name="toolTip">
<string>This is required for accessing your databases from ChromeIPass or PassIFox</string>
</property>
<property name="text">
<string>Enable KeepassXC HTTP protocol
This is required for accessing your databases from ChromeIPass or PassIFox</string>
<string>Enable KeePassHTTP server</string>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
@ -40,13 +51,18 @@ This is required for accessing your databases from ChromeIPass or PassIFox</stri
<property name="text">
<string>Sh&amp;ow a notification when credentials are requested</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="bestMatchOnly">
<property name="toolTip">
<string>Only returns the best matches for a specific URL instead of all entries for the whole domain.</string>
</property>
<property name="text">
<string>&amp;Return only best matching entries for a URL instead
of all entries for the whole domain</string>
<string>&amp;Return only best matching entries</string>
</property>
</widget>
</item>
@ -55,13 +71,18 @@ of all entries for the whole domain</string>
<property name="text">
<string>Re&amp;quest to unlock the database if it is locked</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="matchUrlScheme">
<property name="toolTip">
<string>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</string>
</property>
<property name="text">
<string>&amp;Match URL schemes
Only entries with the same scheme (http://, https://, ftp://, ...) are returned</string>
<string>&amp;Match URL schemes</string>
</property>
</widget>
</item>
@ -110,7 +131,7 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Password generator</string>
<string>Password Generator</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
@ -135,20 +156,14 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<attribute name="title">
<string>Advanced</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>The following options can be dangerous. Change them only if you know what you are doing.</string>
<widget class="MessageWidget" name="warningWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
@ -168,35 +183,21 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</item>
<item>
<widget class="QCheckBox" name="searchInAllDatabases">
<property name="toolTip">
<string>Only the selected database has to be connected with a client.</string>
</property>
<property name="text">
<string>Searc&amp;h in all opened databases for matching entries</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Only the selected database has to be connected with a client!</string>
</property>
<property name="indent">
<number>30</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="supportKphFields">
<property name="text">
<string>&amp;Return advanced string fields which start with &quot;KPH: &quot;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<property name="toolTip">
<string>Automatically creating or updating string fields is not supported.</string>
</property>
<property name="indent">
<number>30</number>
<property name="text">
<string>&amp;Return advanced string fields which start with &quot;KPH: &quot;</string>
</property>
</widget>
</item>
@ -217,25 +218,8 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</spacer>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QLineEdit" name="httpPort">
<property name="inputMask">
<string notr="true">d0000</string>
</property>
<property name="placeholderText">
<string>Default port: 19455</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>KeePassXC will listen to this port on 127.0.0.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -251,6 +235,29 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="httpPort">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="inputMask">
<string notr="true">d0000</string>
</property>
<property name="placeholderText">
<string>Default port: 19455</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>KeePassXC will listen to this port on 127.0.0.1</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -279,6 +286,12 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<header>http/HttpPasswordGeneratorWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>MessageWidget</class>
<extends>QWidget</extends>
<header>gui/MessageWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>