mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Merge github.com:keepassx/keepassx
Conflicts: src/gui/DatabaseWidget.cpp
This commit is contained in:
commit
95fdefdcc7
8
.tx/config
Normal file
8
.tx/config
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[main]
|
||||||
|
host = https://www.transifex.com
|
||||||
|
|
||||||
|
[keepassx.keepassx_ents]
|
||||||
|
source_file = share/translations/keepassx_en.ts
|
||||||
|
file_filter = share/translations/keepassx_<lang>.ts
|
||||||
|
source_lang = en
|
||||||
|
type = QT
|
@ -13,6 +13,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
add_subdirectory(translations)
|
||||||
|
|
||||||
file(GLOB DATABASE_ICONS icons/database/*.png)
|
file(GLOB DATABASE_ICONS icons/database/*.png)
|
||||||
|
|
||||||
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
|
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
|
||||||
|
26
share/translations/CMakeLists.txt
Normal file
26
share/translations/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
file(GLOB TRANSLATION_FILES *.ts)
|
||||||
|
get_filename_component(TRANSLATION_EN_ABS keepassx_en.ts ABSOLUTE)
|
||||||
|
list(REMOVE_ITEM TRANSLATION_FILES keepassx_en.ts)
|
||||||
|
list(REMOVE_ITEM TRANSLATION_FILES ${TRANSLATION_EN_ABS})
|
||||||
|
message(STATUS ${TRANSLATION_FILES})
|
||||||
|
|
||||||
|
qt4_add_translation(QM_FILES ${TRANSLATION_FILES})
|
||||||
|
|
||||||
|
install(FILES ${QM_FILES} DESTINATION ${DATA_INSTALL_DIR}/translations)
|
||||||
|
add_custom_target(translations DEPENDS ${QM_FILES})
|
||||||
|
add_dependencies(${PROGNAME} translations)
|
1175
share/translations/keepassx_de.ts
Normal file
1175
share/translations/keepassx_de.ts
Normal file
File diff suppressed because it is too large
Load Diff
1189
share/translations/keepassx_en.ts
Normal file
1189
share/translations/keepassx_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
41
share/translations/keepassx_en_plurals.ts
Normal file
41
share/translations/keepassx_en_plurals.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.0" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>DatabaseWidget</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Do you really want to move %n entry(s) to the recycle bin?</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Do you really want to move %n entry to the recycle bin?</numerusform>
|
||||||
|
<numerusform>Do you really want to move %n entries to the recycle bin?</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>EditEntryWidget</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n week(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n week</numerusform>
|
||||||
|
<numerusform>%n weeks</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n month(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n month</numerusform>
|
||||||
|
<numerusform>%n months</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>EditWidgetIcons</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Can't delete icon. Still used by %n item(s).</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Can't delete icon. Still used by %n item.</numerusform>
|
||||||
|
<numerusform>Can't delete icon. Still used by %n items.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
8
share/translations/update.sh
Executable file
8
share/translations/update.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
BASEDIR=$(dirname $0)
|
||||||
|
|
||||||
|
cd $BASEDIR/../..
|
||||||
|
|
||||||
|
lupdate -no-ui-lines -disable-heuristic similartext -locations none -no-obsolete src -ts share/translations/keepassx_en.ts
|
||||||
|
lupdate -no-ui-lines -disable-heuristic similartext -locations none -pluralonly src -ts share/translations/keepassx_en_plurals.ts
|
@ -36,6 +36,7 @@ set(keepassx_SOURCES
|
|||||||
core/Entry.cpp
|
core/Entry.cpp
|
||||||
core/EntryAttachments.cpp
|
core/EntryAttachments.cpp
|
||||||
core/EntryAttributes.cpp
|
core/EntryAttributes.cpp
|
||||||
|
core/EntrySearcher.cpp
|
||||||
core/FilePath.cpp
|
core/FilePath.cpp
|
||||||
core/Global.h
|
core/Global.h
|
||||||
core/Group.cpp
|
core/Group.cpp
|
||||||
@ -48,7 +49,9 @@ set(keepassx_SOURCES
|
|||||||
core/SignalMultiplexer.cpp
|
core/SignalMultiplexer.cpp
|
||||||
core/TimeDelta.cpp
|
core/TimeDelta.cpp
|
||||||
core/TimeInfo.cpp
|
core/TimeInfo.cpp
|
||||||
|
core/ToDbExporter.cpp
|
||||||
core/Tools.cpp
|
core/Tools.cpp
|
||||||
|
core/Translator.cpp
|
||||||
core/Uuid.cpp
|
core/Uuid.cpp
|
||||||
core/qcommandlineoption.cpp
|
core/qcommandlineoption.cpp
|
||||||
core/qcommandlineparser.cpp
|
core/qcommandlineparser.cpp
|
||||||
@ -74,6 +77,7 @@ set(keepassx_SOURCES
|
|||||||
gui/DatabaseSettingsWidget.cpp
|
gui/DatabaseSettingsWidget.cpp
|
||||||
gui/DatabaseTabWidget.cpp
|
gui/DatabaseTabWidget.cpp
|
||||||
gui/DatabaseWidget.cpp
|
gui/DatabaseWidget.cpp
|
||||||
|
gui/DatabaseWidgetStateSync.cpp
|
||||||
gui/DialogyWidget.cpp
|
gui/DialogyWidget.cpp
|
||||||
gui/DragTabBar.cpp
|
gui/DragTabBar.cpp
|
||||||
gui/EditWidget.cpp
|
gui/EditWidget.cpp
|
||||||
@ -156,6 +160,7 @@ set(keepassx_MOC
|
|||||||
gui/DatabaseSettingsWidget.h
|
gui/DatabaseSettingsWidget.h
|
||||||
gui/DatabaseTabWidget.h
|
gui/DatabaseTabWidget.h
|
||||||
gui/DatabaseWidget.h
|
gui/DatabaseWidget.h
|
||||||
|
gui/DatabaseWidgetStateSync.h
|
||||||
gui/DialogyWidget.h
|
gui/DialogyWidget.h
|
||||||
gui/DragTabBar.h
|
gui/DragTabBar.h
|
||||||
gui/EditWidget.h
|
gui/EditWidget.h
|
||||||
|
@ -190,8 +190,10 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
|
|||||||
|
|
||||||
if (entryList.isEmpty()) {
|
if (entryList.isEmpty()) {
|
||||||
m_inAutoType = false;
|
m_inAutoType = false;
|
||||||
MessageBox::information(Q_NULLPTR, tr("Auto-Type - KeePassX"),
|
QString message = tr("Couldn't find an entry that matches the window title:");
|
||||||
tr("Couldn't find an entry that matches the window title."));
|
message.append("\n\n");
|
||||||
|
message.append(windowTitle);
|
||||||
|
MessageBox::information(Q_NULLPTR, tr("Auto-Type - KeePassX"), message);
|
||||||
}
|
}
|
||||||
else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) {
|
else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) {
|
||||||
m_inAutoType = false;
|
m_inAutoType = false;
|
||||||
@ -503,6 +505,12 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->title().isEmpty()
|
||||||
|
&& windowTitle.contains(entry->title(), Qt::CaseInsensitive)) {
|
||||||
|
sequence = entry->defaultAutoTypeSequence();
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
|
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
|
||||||
|
|
||||||
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
||||||
|
#define KEEPASSX_BINARY_DIR "${CMAKE_BINARY_DIR}"
|
||||||
|
|
||||||
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
|
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
|
||||||
|
|
||||||
|
@ -95,12 +95,14 @@ void Config::init(const QString& fileName)
|
|||||||
m_defaults.insert("ShowToolbar", true);
|
m_defaults.insert("ShowToolbar", true);
|
||||||
m_defaults.insert("MinimizeOnCopy", false);
|
m_defaults.insert("MinimizeOnCopy", false);
|
||||||
m_defaults.insert("UseGroupIconOnEntryCreation", false);
|
m_defaults.insert("UseGroupIconOnEntryCreation", false);
|
||||||
|
m_defaults.insert("AutoTypeEntryTitleMatch", true);
|
||||||
m_defaults.insert("security/clearclipboard", true);
|
m_defaults.insert("security/clearclipboard", true);
|
||||||
m_defaults.insert("security/clearclipboardtimeout", 10);
|
m_defaults.insert("security/clearclipboardtimeout", 10);
|
||||||
m_defaults.insert("security/lockdatabaseidle", false);
|
m_defaults.insert("security/lockdatabaseidle", false);
|
||||||
m_defaults.insert("security/lockdatabaseidlesec", 10);
|
m_defaults.insert("security/lockdatabaseidlesec", 10);
|
||||||
m_defaults.insert("security/passwordscleartext", false);
|
m_defaults.insert("security/passwordscleartext", false);
|
||||||
m_defaults.insert("security/autotypeask", false);
|
m_defaults.insert("security/autotypeask", true);
|
||||||
|
m_defaults.insert("GUI/Language", "system");
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* Config::instance()
|
Config* Config::instance()
|
||||||
@ -112,7 +114,7 @@ Config* Config::instance()
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::createConfigFromFile(QString file)
|
void Config::createConfigFromFile(const QString& file)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_instance);
|
Q_ASSERT(!m_instance);
|
||||||
m_instance = new Config(file, qApp);
|
m_instance = new Config(file, qApp);
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
void set(const QString& key, const QVariant& value);
|
void set(const QString& key, const QVariant& value);
|
||||||
|
|
||||||
static Config* instance();
|
static Config* instance();
|
||||||
static void createConfigFromFile(QString file);
|
static void createConfigFromFile(const QString& file);
|
||||||
static void createTempFileInstance();
|
static void createTempFileInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -579,25 +579,6 @@ const Database* Entry::database() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entry::match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity)
|
|
||||||
{
|
|
||||||
QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
|
|
||||||
Q_FOREACH (const QString& word, wordList) {
|
|
||||||
if (!wordMatch(word, caseSensitivity)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Entry::wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity)
|
|
||||||
{
|
|
||||||
return title().contains(word, caseSensitivity) ||
|
|
||||||
username().contains(word, caseSensitivity) ||
|
|
||||||
url().contains(word, caseSensitivity) ||
|
|
||||||
notes().contains(word, caseSensitivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Entry::resolvePlaceholders(const QString& str) const
|
QString Entry::resolvePlaceholders(const QString& str) const
|
||||||
{
|
{
|
||||||
QString result = str;
|
QString result = str;
|
||||||
|
@ -141,7 +141,6 @@ public:
|
|||||||
void setGroup(Group* group);
|
void setGroup(Group* group);
|
||||||
|
|
||||||
void setUpdateTimeinfo(bool value);
|
void setUpdateTimeinfo(bool value);
|
||||||
bool match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
@ -157,7 +156,6 @@ private Q_SLOTS:
|
|||||||
void updateModifiedSinceBegin();
|
void updateModifiedSinceBegin();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity);
|
|
||||||
const Database* database() const;
|
const Database* database() const;
|
||||||
template <class T> bool set(T& property, const T& value);
|
template <class T> bool set(T& property, const T& value);
|
||||||
|
|
||||||
|
65
src/core/EntrySearcher.cpp
Normal file
65
src/core/EntrySearcher.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "EntrySearcher.h"
|
||||||
|
|
||||||
|
#include "core/Group.h"
|
||||||
|
|
||||||
|
QList<Entry*> EntrySearcher::search(const QString &searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
|
||||||
|
{
|
||||||
|
if (!group->resolveSearchingEnabled()) {
|
||||||
|
return QList<Entry*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return searchEntries(searchTerm, group, caseSensitivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
|
||||||
|
{
|
||||||
|
QList<Entry*> searchResult;
|
||||||
|
|
||||||
|
Q_FOREACH (Entry* entry, group->entries()) {
|
||||||
|
searchResult.append(matchEntry(searchTerm, entry, caseSensitivity));
|
||||||
|
}
|
||||||
|
Q_FOREACH (Group* childGroup, group->children()) {
|
||||||
|
if (childGroup->searchingEnabled() != Group::Disable) {
|
||||||
|
searchResult.append(searchEntries(searchTerm, childGroup, caseSensitivity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return searchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity)
|
||||||
|
{
|
||||||
|
QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
|
||||||
|
Q_FOREACH (const QString& word, wordList) {
|
||||||
|
if (!wordMatch(word, entry, caseSensitivity)) {
|
||||||
|
return QList<Entry*>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QList<Entry*>() << entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
|
||||||
|
{
|
||||||
|
return entry->title().contains(word, caseSensitivity) ||
|
||||||
|
entry->username().contains(word, caseSensitivity) ||
|
||||||
|
entry->url().contains(word, caseSensitivity) ||
|
||||||
|
entry->notes().contains(word, caseSensitivity);
|
||||||
|
}
|
37
src/core/EntrySearcher.h
Normal file
37
src/core/EntrySearcher.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Florian Geyer <debfx@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_ENTRYSEARCHER_H
|
||||||
|
#define KEEPASSX_ENTRYSEARCHER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
|
||||||
|
class Group;
|
||||||
|
class Entry;
|
||||||
|
|
||||||
|
class EntrySearcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QList<Entry*> search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
|
||||||
|
private:
|
||||||
|
QList<Entry*> searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
|
||||||
|
QList<Entry*> matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity);
|
||||||
|
bool wordMatch(const QString &word, Entry *entry, Qt::CaseSensitivity caseSensitivity);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_ENTRYSEARCHER_H
|
14
src/core/Exporter.h
Normal file
14
src/core/Exporter.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef KEEPASSX_EXPORTER_H
|
||||||
|
#define KEEPASSX_EXPORTER_H
|
||||||
|
|
||||||
|
class Database;
|
||||||
|
class Group;
|
||||||
|
|
||||||
|
class Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Database* exportGroup(Group* group) = 0;
|
||||||
|
virtual ~Exporter() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_EXPORTER_H
|
@ -500,22 +500,6 @@ void Group::copyDataFrom(const Group* other)
|
|||||||
m_lastTopVisibleEntry = other->m_lastTopVisibleEntry;
|
m_lastTopVisibleEntry = other->m_lastTopVisibleEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database* Group::exportToDb()
|
|
||||||
{
|
|
||||||
Q_ASSERT(database());
|
|
||||||
|
|
||||||
Database* db = new Database();
|
|
||||||
Group* clonedGroup = clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
|
|
||||||
clonedGroup->setParent(db->rootGroup());
|
|
||||||
|
|
||||||
QSet<Uuid> customIcons = customIconsRecursive();
|
|
||||||
db->metadata()->copyCustomIcons(customIcons, database()->metadata());
|
|
||||||
|
|
||||||
db->copyAttributesFrom(database());
|
|
||||||
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Group::addEntry(Entry* entry)
|
void Group::addEntry(Entry* entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(entry);
|
Q_ASSERT(entry);
|
||||||
@ -612,33 +596,6 @@ void Group::recCreateDelObjects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Entry*> Group::search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
|
|
||||||
bool resolveInherit)
|
|
||||||
{
|
|
||||||
QList<Entry*> searchResult;
|
|
||||||
bool search;
|
|
||||||
if (resolveInherit) {
|
|
||||||
search = resolveSearchingEnabled();
|
|
||||||
}
|
|
||||||
else if (searchingEnabled() == Disable) {
|
|
||||||
search = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
search = true;
|
|
||||||
}
|
|
||||||
if (search) {
|
|
||||||
Q_FOREACH (Entry* entry, m_entries) {
|
|
||||||
if (entry->match(searchTerm, caseSensitivity)) {
|
|
||||||
searchResult.append(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Q_FOREACH (Group* group, m_children) {
|
|
||||||
searchResult.append(group->search(searchTerm, caseSensitivity, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return searchResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Group::resolveSearchingEnabled() const
|
bool Group::resolveSearchingEnabled() const
|
||||||
{
|
{
|
||||||
switch (m_data.searchingEnabled) {
|
switch (m_data.searchingEnabled) {
|
||||||
|
@ -111,10 +111,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
|
Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
|
||||||
void copyDataFrom(const Group* other);
|
void copyDataFrom(const Group* other);
|
||||||
Database* exportToDb();
|
|
||||||
|
|
||||||
QList<Entry*> search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
|
|
||||||
bool resolveInherit = true);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void dataChanged(Group* group);
|
void dataChanged(Group* group);
|
||||||
|
39
src/core/ToDbExporter.cpp
Normal file
39
src/core/ToDbExporter.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "ToDbExporter.h"
|
||||||
|
#include "core/Database.h"
|
||||||
|
#include "core/Group.h"
|
||||||
|
#include "core/Metadata.h"
|
||||||
|
|
||||||
|
Database* ToDbExporter::exportGroup(Group* group)
|
||||||
|
{
|
||||||
|
Database* oldDb = group->database();
|
||||||
|
Q_ASSERT(oldDb);
|
||||||
|
|
||||||
|
Database* db = new Database();
|
||||||
|
Group* clonedGroup = group->clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
|
||||||
|
clonedGroup->setParent(db->rootGroup());
|
||||||
|
|
||||||
|
QSet<Uuid> customIcons = group->customIconsRecursive();
|
||||||
|
db->metadata()->copyCustomIcons(customIcons, oldDb->metadata());
|
||||||
|
|
||||||
|
db->copyAttributesFrom(oldDb);
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
33
src/core/ToDbExporter.h
Normal file
33
src/core/ToDbExporter.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_TODBEXPORTER_H
|
||||||
|
#define KEEPASSX_TODBEXPORTER_H
|
||||||
|
|
||||||
|
#include "core/Exporter.h"
|
||||||
|
|
||||||
|
class Database;
|
||||||
|
class Group;
|
||||||
|
|
||||||
|
class ToDbExporter : Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Database* exportGroup(Group* group);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_TODBEXPORTER_H
|
120
src/core/Translator.cpp
Normal file
120
src/core/Translator.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "Translator.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QLibraryInfo>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#include "config-keepassx.h"
|
||||||
|
#include "core/Config.h"
|
||||||
|
#include "core/FilePath.h"
|
||||||
|
|
||||||
|
void Translator::installTranslator()
|
||||||
|
{
|
||||||
|
QString language = config()->get("GUI/Language").toString();
|
||||||
|
if (language == "system" || language.isEmpty()) {
|
||||||
|
language = QLocale::system().name();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!installTranslator(language)) {
|
||||||
|
// English fallback still needs translations for plurals
|
||||||
|
if (!installTranslator("en_plurals")) {
|
||||||
|
qWarning("Couldn't load translations.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
installQtTranslator(language);
|
||||||
|
|
||||||
|
availableLanguages();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > Translator::availableLanguages()
|
||||||
|
{
|
||||||
|
QStringList paths;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
|
||||||
|
#endif
|
||||||
|
paths.append(filePath()->dataPath("translations"));
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > languages;
|
||||||
|
languages.append(QPair<QString, QString>("system", "System default"));
|
||||||
|
|
||||||
|
QRegExp regExp("keepassx_([a-zA-Z_]+)\\.qm", Qt::CaseInsensitive, QRegExp::RegExp2);
|
||||||
|
Q_FOREACH (const QString& path, paths) {
|
||||||
|
Q_FOREACH (const QString& filename, QDir(path).entryList()) {
|
||||||
|
if (regExp.exactMatch(filename)) {
|
||||||
|
QString langcode = regExp.cap(1);
|
||||||
|
if (langcode == "en_plurals") {
|
||||||
|
langcode = "en";
|
||||||
|
}
|
||||||
|
|
||||||
|
languages.append(QPair<QString, QString>(langcode,
|
||||||
|
QLocale::languageToString(QLocale(langcode).language())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installTranslator(const QString& language)
|
||||||
|
{
|
||||||
|
QStringList paths;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
|
||||||
|
#endif
|
||||||
|
paths.append(filePath()->dataPath("translations"));
|
||||||
|
|
||||||
|
Q_FOREACH (const QString& path, paths) {
|
||||||
|
if (installTranslator(language, path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installTranslator(const QString& language, const QString& path)
|
||||||
|
{
|
||||||
|
QTranslator* translator = new QTranslator(qApp);
|
||||||
|
if (translator->load(QString("keepassx_").append(language), path)) {
|
||||||
|
QCoreApplication::installTranslator(translator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete translator;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installQtTranslator(const QString& language)
|
||||||
|
{
|
||||||
|
QTranslator* qtTranslator = new QTranslator(qApp);
|
||||||
|
if (qtTranslator->load(QString("%1/qt_%2").arg(QLibraryInfo::location(QLibraryInfo::TranslationsPath), language))) {
|
||||||
|
QCoreApplication::installTranslator(qtTranslator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete qtTranslator;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
36
src/core/Translator.h
Normal file
36
src/core/Translator.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_TRANSLATOR_H
|
||||||
|
#define KEEPASSX_TRANSLATOR_H
|
||||||
|
|
||||||
|
#include <QPair>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class Translator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void installTranslator();
|
||||||
|
static QList<QPair<QString, QString> > availableLanguages();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool installTranslator(const QString& language);
|
||||||
|
static bool installTranslator(const QString& language, const QString& path);
|
||||||
|
static bool installQtTranslator(const QString& language);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_TRANSLATOR_H
|
@ -51,6 +51,7 @@ void Clipboard::setText(const QString& text)
|
|||||||
if (config()->get("security/clearclipboard").toBool()) {
|
if (config()->get("security/clearclipboard").toBool()) {
|
||||||
int timeout = config()->get("security/clearclipboardtimeout").toInt();
|
int timeout = config()->get("security/clearclipboardtimeout").toInt();
|
||||||
if (timeout > 0) {
|
if (timeout > 0) {
|
||||||
|
m_lastCopied = text;
|
||||||
m_timer->start(timeout * 1000);
|
m_timer->start(timeout * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,8 +66,12 @@ void Clipboard::clearClipboard()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard->clear(QClipboard::Clipboard);
|
if (clipboard->text(QClipboard::Clipboard) == m_lastCopied) {
|
||||||
if (clipboard->supportsSelection()) {
|
clipboard->clear(QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clipboard->supportsSelection()
|
||||||
|
&& (clipboard->text(QClipboard::Selection) == m_lastCopied)) {
|
||||||
clipboard->clear(QClipboard::Selection);
|
clipboard->clear(QClipboard::Selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +79,8 @@ void Clipboard::clearClipboard()
|
|||||||
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.klipper", "/klipper", "", "clearClipboardHistory");
|
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.klipper", "/klipper", "", "clearClipboardHistory");
|
||||||
QDBusConnection::sessionBus().send(message);
|
QDBusConnection::sessionBus().send(message);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_lastCopied.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clipboard::cleanup()
|
void Clipboard::cleanup()
|
||||||
|
@ -43,6 +43,7 @@ private:
|
|||||||
static Clipboard* m_instance;
|
static Clipboard* m_instance;
|
||||||
|
|
||||||
QTimer* m_timer;
|
QTimer* m_timer;
|
||||||
|
QString m_lastCopied;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Clipboard* clipboard() {
|
inline Clipboard* clipboard() {
|
||||||
|
@ -117,8 +117,8 @@ void DatabaseOpenWidget::openDatabase()
|
|||||||
Q_EMIT editFinished(true);
|
Q_EMIT editFinished(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.\n%1")
|
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
|
||||||
.arg(reader.errorString()));
|
.append(reader.errorString()));
|
||||||
m_ui->editPassword->clear();
|
m_ui->editPassword->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ CompositeKey DatabaseOpenWidget::databaseKey()
|
|||||||
QString keyFilename = m_ui->comboKeyFile->currentText();
|
QString keyFilename = m_ui->comboKeyFile->currentText();
|
||||||
QString errorMsg;
|
QString errorMsg;
|
||||||
if (!key.load(keyFilename, &errorMsg)) {
|
if (!key.load(keyFilename, &errorMsg)) {
|
||||||
MessageBox::warning(this, tr("Error"), tr("Can't open key file:\n%1").arg(errorMsg));
|
MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg));
|
||||||
return CompositeKey();
|
return CompositeKey();
|
||||||
}
|
}
|
||||||
masterKey.addKey(key);
|
masterKey.addKey(key);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "core/Metadata.h"
|
#include "core/Metadata.h"
|
||||||
#include "core/qsavefile.h"
|
#include "core/qsavefile.h"
|
||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
|
#include "gui/DatabaseWidgetStateSync.h"
|
||||||
#include "gui/DragTabBar.h"
|
#include "gui/DragTabBar.h"
|
||||||
#include "gui/FileDialog.h"
|
#include "gui/FileDialog.h"
|
||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
@ -46,12 +47,15 @@ const int DatabaseTabWidget::LastDatabasesCount = 5;
|
|||||||
|
|
||||||
DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
|
DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
|
||||||
: QTabWidget(parent)
|
: QTabWidget(parent)
|
||||||
|
, m_dbWidgetSateSync(new DatabaseWidgetStateSync(this))
|
||||||
{
|
{
|
||||||
DragTabBar* tabBar = new DragTabBar(this);
|
DragTabBar* tabBar = new DragTabBar(this);
|
||||||
tabBar->setDrawBase(false);
|
tabBar->setDrawBase(false);
|
||||||
setTabBar(tabBar);
|
setTabBar(tabBar);
|
||||||
|
|
||||||
connect(this, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
|
connect(this, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
|
||||||
|
connect(this, SIGNAL(currentChanged(int)), SLOT(emitActivateDatabaseChanged()));
|
||||||
|
connect(this, SIGNAL(activateDatabaseChanged(DatabaseWidget*)), m_dbWidgetSateSync, SLOT(setActive(DatabaseWidget*)));
|
||||||
connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType()));
|
connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +193,7 @@ bool DatabaseTabWidget::closeDatabase(Database* db)
|
|||||||
if (dbName.right(1) == "*") {
|
if (dbName.right(1) == "*") {
|
||||||
dbName.chop(1);
|
dbName.chop(1);
|
||||||
}
|
}
|
||||||
if (dbStruct.dbWidget->currentMode() == DatabaseWidget::EditMode && db->hasKey()) {
|
if (dbStruct.dbWidget->isInEditMode() && db->hasKey()) {
|
||||||
QMessageBox::StandardButton result =
|
QMessageBox::StandardButton result =
|
||||||
MessageBox::question(
|
MessageBox::question(
|
||||||
this, tr("Close?"),
|
this, tr("Close?"),
|
||||||
@ -503,7 +507,7 @@ DatabaseWidget* DatabaseTabWidget::currentDatabaseWidget()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseTabWidget::hasLockableDatabases()
|
bool DatabaseTabWidget::hasLockableDatabases() const
|
||||||
{
|
{
|
||||||
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
|
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
@ -584,6 +588,11 @@ void DatabaseTabWidget::changeDatabase(Database* newDb)
|
|||||||
connectDatabase(newDb, oldDb);
|
connectDatabase(newDb, oldDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseTabWidget::emitActivateDatabaseChanged()
|
||||||
|
{
|
||||||
|
Q_EMIT activateDatabaseChanged(currentDatabaseWidget());
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseTabWidget::connectDatabase(Database* newDb, Database* oldDb)
|
void DatabaseTabWidget::connectDatabase(Database* newDb, Database* oldDb)
|
||||||
{
|
{
|
||||||
if (oldDb) {
|
if (oldDb) {
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
|
|
||||||
class DatabaseWidget;
|
class DatabaseWidget;
|
||||||
|
class DatabaseWidgetStateSync;
|
||||||
class DatabaseOpenWidget;
|
class DatabaseOpenWidget;
|
||||||
class QFile;
|
class QFile;
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ public:
|
|||||||
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
||||||
const QString& keyFile = QString());
|
const QString& keyFile = QString());
|
||||||
DatabaseWidget* currentDatabaseWidget();
|
DatabaseWidget* currentDatabaseWidget();
|
||||||
bool hasLockableDatabases();
|
bool hasLockableDatabases() const;
|
||||||
|
|
||||||
static const int LastDatabasesCount;
|
static const int LastDatabasesCount;
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ public Q_SLOTS:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void tabNameChanged();
|
void tabNameChanged();
|
||||||
void databaseWithFileClosed(QString filePath);
|
void databaseWithFileClosed(QString filePath);
|
||||||
|
void activateDatabaseChanged(DatabaseWidget* dbWidget);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateTabName(Database* db);
|
void updateTabName(Database* db);
|
||||||
@ -83,6 +85,7 @@ private Q_SLOTS:
|
|||||||
void modified();
|
void modified();
|
||||||
void toggleTabbar();
|
void toggleTabbar();
|
||||||
void changeDatabase(Database* newDb);
|
void changeDatabase(Database* newDb);
|
||||||
|
void emitActivateDatabaseChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveDatabase(Database* db);
|
void saveDatabase(Database* db);
|
||||||
@ -99,6 +102,7 @@ private:
|
|||||||
|
|
||||||
KeePass2Writer m_writer;
|
KeePass2Writer m_writer;
|
||||||
QHash<Database*, DatabaseManagerStruct> m_dbList;
|
QHash<Database*, DatabaseManagerStruct> m_dbList;
|
||||||
|
DatabaseWidgetStateSync* m_dbWidgetSateSync;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_DATABASETABWIDGET_H
|
#endif // KEEPASSX_DATABASETABWIDGET_H
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "autotype/AutoType.h"
|
#include "autotype/AutoType.h"
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
|
#include "core/EntrySearcher.h"
|
||||||
#include "core/FilePath.h"
|
#include "core/FilePath.h"
|
||||||
#include "core/Group.h"
|
#include "core/Group.h"
|
||||||
#include "core/Metadata.h"
|
#include "core/Metadata.h"
|
||||||
@ -63,12 +64,13 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||||||
|
|
||||||
m_mainWidget = new QWidget(this);
|
m_mainWidget = new QWidget(this);
|
||||||
QLayout* layout = new QHBoxLayout(m_mainWidget);
|
QLayout* layout = new QHBoxLayout(m_mainWidget);
|
||||||
QSplitter* splitter = new QSplitter(m_mainWidget);
|
m_splitter = new QSplitter(m_mainWidget);
|
||||||
|
m_splitter->setChildrenCollapsible(false);
|
||||||
|
|
||||||
QWidget* rightHandSideWidget = new QWidget(splitter);
|
QWidget* rightHandSideWidget = new QWidget(m_splitter);
|
||||||
m_searchWidget->setParent(rightHandSideWidget);
|
m_searchWidget->setParent(rightHandSideWidget);
|
||||||
|
|
||||||
m_groupView = new GroupView(db, splitter);
|
m_groupView = new GroupView(db, m_splitter);
|
||||||
m_groupView->setObjectName("groupView");
|
m_groupView->setObjectName("groupView");
|
||||||
m_groupView->setContextMenuPolicy(Qt::CustomContextMenu);
|
m_groupView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)),
|
connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)),
|
||||||
@ -81,14 +83,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||||||
connect(m_entryView, SIGNAL(customContextMenuRequested(QPoint)),
|
connect(m_entryView, SIGNAL(customContextMenuRequested(QPoint)),
|
||||||
SLOT(emitEntryContextMenuRequested(QPoint)));
|
SLOT(emitEntryContextMenuRequested(QPoint)));
|
||||||
|
|
||||||
QSizePolicy policy;
|
|
||||||
policy = m_groupView->sizePolicy();
|
|
||||||
policy.setHorizontalStretch(30);
|
|
||||||
m_groupView->setSizePolicy(policy);
|
|
||||||
policy = rightHandSideWidget->sizePolicy();
|
|
||||||
policy.setHorizontalStretch(70);
|
|
||||||
rightHandSideWidget->setSizePolicy(policy);
|
|
||||||
|
|
||||||
QAction* closeAction = new QAction(m_searchWidget);
|
QAction* closeAction = new QAction(m_searchWidget);
|
||||||
QIcon closeIcon = filePath()->icon("actions", "dialog-close");
|
QIcon closeIcon = filePath()->icon("actions", "dialog-close");
|
||||||
closeAction->setIcon(closeIcon);
|
closeAction->setIcon(closeIcon);
|
||||||
@ -104,10 +98,17 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||||||
|
|
||||||
rightHandSideWidget->setLayout(vLayout);
|
rightHandSideWidget->setLayout(vLayout);
|
||||||
|
|
||||||
splitter->addWidget(m_groupView);
|
setTabOrder(m_searchUi->searchRootRadioButton, m_entryView);
|
||||||
splitter->addWidget(rightHandSideWidget);
|
setTabOrder(m_entryView, m_groupView);
|
||||||
|
setTabOrder(m_groupView, m_searchWidget);
|
||||||
|
|
||||||
layout->addWidget(splitter);
|
m_splitter->addWidget(m_groupView);
|
||||||
|
m_splitter->addWidget(rightHandSideWidget);
|
||||||
|
|
||||||
|
m_splitter->setStretchFactor(0, 30);
|
||||||
|
m_splitter->setStretchFactor(1, 70);
|
||||||
|
|
||||||
|
layout->addWidget(m_splitter);
|
||||||
m_mainWidget->setLayout(layout);
|
m_mainWidget->setLayout(layout);
|
||||||
|
|
||||||
m_editEntryWidget = new EditEntryWidget();
|
m_editEntryWidget = new EditEntryWidget();
|
||||||
@ -139,6 +140,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||||||
addWidget(m_keepass1OpenWidget);
|
addWidget(m_keepass1OpenWidget);
|
||||||
addWidget(m_unlockDatabaseWidget);
|
addWidget(m_unlockDatabaseWidget);
|
||||||
|
|
||||||
|
connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged()));
|
||||||
|
connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged()));
|
||||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*)));
|
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*)));
|
||||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
||||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
|
connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
|
||||||
@ -171,7 +174,7 @@ DatabaseWidget::~DatabaseWidget()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseWidget::Mode DatabaseWidget::currentMode()
|
DatabaseWidget::Mode DatabaseWidget::currentMode() const
|
||||||
{
|
{
|
||||||
if (currentWidget() == Q_NULLPTR) {
|
if (currentWidget() == Q_NULLPTR) {
|
||||||
return DatabaseWidget::None;
|
return DatabaseWidget::None;
|
||||||
@ -187,21 +190,56 @@ DatabaseWidget::Mode DatabaseWidget::currentMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DatabaseWidget::isInEditMode() const
|
||||||
|
{
|
||||||
|
if (currentMode() == DatabaseWidget::LockedMode) {
|
||||||
|
return m_widgetBeforeLock != Q_NULLPTR
|
||||||
|
&& m_widgetBeforeLock != m_mainWidget
|
||||||
|
&& m_widgetBeforeLock != m_unlockDatabaseWidget;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return currentMode() == DatabaseWidget::EditMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> DatabaseWidget::splitterSizes() const
|
||||||
|
{
|
||||||
|
return m_splitter->sizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidget::setSplitterSizes(const QList<int>& sizes)
|
||||||
|
{
|
||||||
|
m_splitter->setSizes(sizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> DatabaseWidget::entryHeaderViewSizes() const
|
||||||
|
{
|
||||||
|
QList<int> sizes;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_entryView->header()->count(); i++) {
|
||||||
|
sizes.append(m_entryView->header()->sectionSize(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidget::setEntryViewHeaderSizes(const QList<int>& sizes)
|
||||||
|
{
|
||||||
|
if (sizes.size() != m_entryView->header()->count()) {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < sizes.size(); i++) {
|
||||||
|
m_entryView->header()->resizeSection(i, sizes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseWidget::emitCurrentModeChanged()
|
void DatabaseWidget::emitCurrentModeChanged()
|
||||||
{
|
{
|
||||||
Q_EMIT currentModeChanged(currentMode());
|
Q_EMIT currentModeChanged(currentMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupView* DatabaseWidget::groupView()
|
|
||||||
{
|
|
||||||
return m_groupView;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntryView* DatabaseWidget::entryView()
|
|
||||||
{
|
|
||||||
return m_entryView;
|
|
||||||
}
|
|
||||||
|
|
||||||
Database* DatabaseWidget::database()
|
Database* DatabaseWidget::database()
|
||||||
{
|
{
|
||||||
return m_db;
|
return m_db;
|
||||||
@ -298,8 +336,7 @@ void DatabaseWidget::deleteEntries()
|
|||||||
if (selected.size() > 1) {
|
if (selected.size() > 1) {
|
||||||
QMessageBox::StandardButton result = MessageBox::question(
|
QMessageBox::StandardButton result = MessageBox::question(
|
||||||
this, tr("Move entries to recycle bin?"),
|
this, tr("Move entries to recycle bin?"),
|
||||||
tr("Do you really want to move %1 entries to the recycle bin?")
|
tr("Do you really want to move %n entry(s) to the recycle bin?", 0, selected.size()),
|
||||||
.arg(selected.size()),
|
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
if (result == QMessageBox::No) {
|
if (result == QMessageBox::No) {
|
||||||
return;
|
return;
|
||||||
@ -431,7 +468,7 @@ void DatabaseWidget::createGroup()
|
|||||||
void DatabaseWidget::deleteGroup()
|
void DatabaseWidget::deleteGroup()
|
||||||
{
|
{
|
||||||
Group* currentGroup = m_groupView->currentGroup();
|
Group* currentGroup = m_groupView->currentGroup();
|
||||||
if (!currentGroup || !canDeleteCurrentGoup()) {
|
if (!currentGroup || !canDeleteCurrentGroup()) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -601,7 +638,7 @@ void DatabaseWidget::unlockDatabase(bool accepted)
|
|||||||
Q_ASSERT(accepted);
|
Q_ASSERT(accepted);
|
||||||
Q_UNUSED(accepted);
|
Q_UNUSED(accepted);
|
||||||
|
|
||||||
setCurrentWidget(widgetBeforeLock);
|
setCurrentWidget(m_widgetBeforeLock);
|
||||||
Q_EMIT unlockedDatabase();
|
Q_EMIT unlockedDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,8 +710,16 @@ void DatabaseWidget::switchToImportKeepass1(const QString& fileName)
|
|||||||
|
|
||||||
void DatabaseWidget::toggleSearch()
|
void DatabaseWidget::toggleSearch()
|
||||||
{
|
{
|
||||||
if (m_entryView->inEntryListMode()) {
|
if (isInSearchMode()) {
|
||||||
closeSearch();
|
if (m_searchUi->searchEdit->hasFocus()) {
|
||||||
|
closeSearch();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_searchUi->searchEdit->selectAll();
|
||||||
|
m_searchUi->searchEdit->setFocus();
|
||||||
|
// make sure the search action is checked again
|
||||||
|
emitCurrentModeChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
showSearch();
|
showSearch();
|
||||||
@ -684,11 +729,19 @@ void DatabaseWidget::toggleSearch()
|
|||||||
void DatabaseWidget::closeSearch()
|
void DatabaseWidget::closeSearch()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_lastGroup);
|
Q_ASSERT(m_lastGroup);
|
||||||
|
|
||||||
|
Q_EMIT listModeAboutToActivate();
|
||||||
|
|
||||||
m_groupView->setCurrentGroup(m_lastGroup);
|
m_groupView->setCurrentGroup(m_lastGroup);
|
||||||
|
m_searchTimer->stop();
|
||||||
|
|
||||||
|
Q_EMIT listModeActivated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::showSearch()
|
void DatabaseWidget::showSearch()
|
||||||
{
|
{
|
||||||
|
Q_EMIT searchModeAboutToActivate();
|
||||||
|
|
||||||
m_searchUi->searchEdit->blockSignals(true);
|
m_searchUi->searchEdit->blockSignals(true);
|
||||||
m_searchUi->searchEdit->clear();
|
m_searchUi->searchEdit->clear();
|
||||||
m_searchUi->searchEdit->blockSignals(false);
|
m_searchUi->searchEdit->blockSignals(false);
|
||||||
@ -722,6 +775,8 @@ void DatabaseWidget::showSearch()
|
|||||||
m_searchWidget->show();
|
m_searchWidget->show();
|
||||||
search();
|
search();
|
||||||
m_searchUi->searchEdit->setFocus();
|
m_searchUi->searchEdit->setFocus();
|
||||||
|
|
||||||
|
Q_EMIT searchModeActivated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::search()
|
void DatabaseWidget::search()
|
||||||
@ -747,8 +802,8 @@ void DatabaseWidget::search()
|
|||||||
else {
|
else {
|
||||||
sensitivity = Qt::CaseInsensitive;
|
sensitivity = Qt::CaseInsensitive;
|
||||||
}
|
}
|
||||||
QList<Entry*> searchResult = searchGroup->search(m_searchUi->searchEdit->text(), sensitivity);
|
|
||||||
|
|
||||||
|
QList<Entry*> searchResult = EntrySearcher().search(m_searchUi->searchEdit->text(), searchGroup, sensitivity);
|
||||||
|
|
||||||
m_entryView->setEntryList(searchResult);
|
m_entryView->setEntryList(searchResult);
|
||||||
}
|
}
|
||||||
@ -779,19 +834,19 @@ void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos)
|
|||||||
Q_EMIT entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
|
Q_EMIT entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseWidget::dbHasKey()
|
bool DatabaseWidget::dbHasKey() const
|
||||||
{
|
{
|
||||||
return m_db->hasKey();
|
return m_db->hasKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseWidget::canDeleteCurrentGoup()
|
bool DatabaseWidget::canDeleteCurrentGroup() const
|
||||||
{
|
{
|
||||||
bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();
|
bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();
|
||||||
bool isRecycleBin = m_db->metadata()->recycleBin() == m_groupView->currentGroup();
|
bool isRecycleBin = m_db->metadata()->recycleBin() == m_groupView->currentGroup();
|
||||||
return !isRootGroup && !isRecycleBin;
|
return !isRootGroup && !isRecycleBin;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseWidget::isInSearchMode()
|
bool DatabaseWidget::isInSearchMode() const
|
||||||
{
|
{
|
||||||
return m_entryView->inEntryListMode();
|
return m_entryView->inEntryListMode();
|
||||||
}
|
}
|
||||||
@ -808,7 +863,7 @@ void DatabaseWidget::lock()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(currentMode() != DatabaseWidget::LockedMode);
|
Q_ASSERT(currentMode() != DatabaseWidget::LockedMode);
|
||||||
|
|
||||||
widgetBeforeLock = currentWidget();
|
m_widgetBeforeLock = currentWidget();
|
||||||
m_unlockDatabaseWidget->load(m_filename, m_db);
|
m_unlockDatabaseWidget->load(m_filename, m_db);
|
||||||
setCurrentWidget(m_unlockDatabaseWidget);
|
setCurrentWidget(m_unlockDatabaseWidget);
|
||||||
}
|
}
|
||||||
@ -839,3 +894,23 @@ void DatabaseWidget::databaseModifedExternally()
|
|||||||
delete oldDb;
|
delete oldDb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DatabaseWidget::numberOfSelectedEntries() const
|
||||||
|
{
|
||||||
|
return m_entryView->numberOfSelectedEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DatabaseWidget::customEntryAttributes() const
|
||||||
|
{
|
||||||
|
Entry* entry = m_entryView->currentEntry();
|
||||||
|
if (!entry) {
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry->attributes()->customKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseWidget::isGroupSelected() const
|
||||||
|
{
|
||||||
|
return m_groupView->currentGroup() != Q_NULLPTR;
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ class GroupView;
|
|||||||
class KeePass1OpenWidget;
|
class KeePass1OpenWidget;
|
||||||
class QFile;
|
class QFile;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
class QSplitter;
|
||||||
class UnlockDatabaseWidget;
|
class UnlockDatabaseWidget;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -60,18 +61,24 @@ public:
|
|||||||
|
|
||||||
explicit DatabaseWidget(Database* db, QWidget* parent = Q_NULLPTR);
|
explicit DatabaseWidget(Database* db, QWidget* parent = Q_NULLPTR);
|
||||||
~DatabaseWidget();
|
~DatabaseWidget();
|
||||||
GroupView* groupView();
|
|
||||||
EntryView* entryView();
|
|
||||||
Database* database();
|
Database* database();
|
||||||
bool dbHasKey();
|
bool dbHasKey() const;
|
||||||
bool canDeleteCurrentGoup();
|
bool canDeleteCurrentGroup() const;
|
||||||
bool isInSearchMode();
|
bool isInSearchMode() const;
|
||||||
int addWidget(QWidget* w);
|
int addWidget(QWidget* w);
|
||||||
void setCurrentIndex(int index);
|
void setCurrentIndex(int index);
|
||||||
void setCurrentWidget(QWidget* widget);
|
void setCurrentWidget(QWidget* widget);
|
||||||
DatabaseWidget::Mode currentMode();
|
DatabaseWidget::Mode currentMode() const;
|
||||||
void lock();
|
void lock();
|
||||||
void updateFilename(const QString& filename);
|
void updateFilename(const QString& filename);
|
||||||
|
int numberOfSelectedEntries() const;
|
||||||
|
QStringList customEntryAttributes() const;
|
||||||
|
bool isGroupSelected() const;
|
||||||
|
bool isInEditMode() const;
|
||||||
|
QList<int> splitterSizes() const;
|
||||||
|
void setSplitterSizes(const QList<int>& sizes);
|
||||||
|
QList<int> entryHeaderViewSizes() const;
|
||||||
|
void setEntryViewHeaderSizes(const QList<int>& sizes);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
@ -82,6 +89,12 @@ Q_SIGNALS:
|
|||||||
void groupContextMenuRequested(const QPoint& globalPos);
|
void groupContextMenuRequested(const QPoint& globalPos);
|
||||||
void entryContextMenuRequested(const QPoint& globalPos);
|
void entryContextMenuRequested(const QPoint& globalPos);
|
||||||
void unlockedDatabase();
|
void unlockedDatabase();
|
||||||
|
void listModeAboutToActivate();
|
||||||
|
void listModeActivated();
|
||||||
|
void searchModeAboutToActivate();
|
||||||
|
void searchModeActivated();
|
||||||
|
void splitterSizesChanged();
|
||||||
|
void entryColumnSizesChanged();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void createEntry();
|
void createEntry();
|
||||||
@ -106,8 +119,6 @@ public Q_SLOTS:
|
|||||||
void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
|
void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
|
||||||
void switchToImportKeepass1(const QString& fileName);
|
void switchToImportKeepass1(const QString& fileName);
|
||||||
void toggleSearch();
|
void toggleSearch();
|
||||||
void emitGroupContextMenuRequested(const QPoint& pos);
|
|
||||||
void emitEntryContextMenuRequested(const QPoint& pos);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
|
void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
|
||||||
@ -117,6 +128,8 @@ private Q_SLOTS:
|
|||||||
void switchToEntryEdit(Entry* entry);
|
void switchToEntryEdit(Entry* entry);
|
||||||
void switchToEntryEdit(Entry* entry, bool create);
|
void switchToEntryEdit(Entry* entry, bool create);
|
||||||
void switchToGroupEdit(Group* entry, bool create);
|
void switchToGroupEdit(Group* entry, bool create);
|
||||||
|
void emitGroupContextMenuRequested(const QPoint& pos);
|
||||||
|
void emitEntryContextMenuRequested(const QPoint& pos);
|
||||||
void updateMasterKey(bool accepted);
|
void updateMasterKey(bool accepted);
|
||||||
void openDatabase(bool accepted);
|
void openDatabase(bool accepted);
|
||||||
void databaseModifedExternally();
|
void databaseModifedExternally();
|
||||||
@ -145,6 +158,7 @@ private:
|
|||||||
DatabaseOpenWidget* m_databaseOpenWidget;
|
DatabaseOpenWidget* m_databaseOpenWidget;
|
||||||
KeePass1OpenWidget* m_keepass1OpenWidget;
|
KeePass1OpenWidget* m_keepass1OpenWidget;
|
||||||
UnlockDatabaseWidget* m_unlockDatabaseWidget;
|
UnlockDatabaseWidget* m_unlockDatabaseWidget;
|
||||||
|
QSplitter* m_splitter;
|
||||||
GroupView* m_groupView;
|
GroupView* m_groupView;
|
||||||
EntryView* m_entryView;
|
EntryView* m_entryView;
|
||||||
Group* m_newGroup;
|
Group* m_newGroup;
|
||||||
@ -152,7 +166,7 @@ private:
|
|||||||
Group* m_newParent;
|
Group* m_newParent;
|
||||||
Group* m_lastGroup;
|
Group* m_lastGroup;
|
||||||
QTimer* m_searchTimer;
|
QTimer* m_searchTimer;
|
||||||
QWidget* widgetBeforeLock;
|
QWidget* m_widgetBeforeLock;
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
FileSystemWatcher m_file_watcher;
|
FileSystemWatcher m_file_watcher;
|
||||||
};
|
};
|
||||||
|
154
src/gui/DatabaseWidgetStateSync.cpp
Normal file
154
src/gui/DatabaseWidgetStateSync.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "DatabaseWidgetStateSync.h"
|
||||||
|
|
||||||
|
#include "core/Config.h"
|
||||||
|
|
||||||
|
DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_activeDbWidget(Q_NULLPTR)
|
||||||
|
, m_blockUpdates(false)
|
||||||
|
{
|
||||||
|
m_splitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
|
||||||
|
m_columnSizesList = variantToIntList(config()->get("GUI/EntryListColumnSizes"));
|
||||||
|
m_columnSizesSearch = variantToIntList(config()->get("GUI/EntrySearchColumnSizes"));
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
||||||
|
{
|
||||||
|
config()->set("GUI/SplitterState", intListToVariant(m_splitterSizes));
|
||||||
|
config()->set("GUI/EntryListColumnSizes", intListToVariant(m_columnSizesList));
|
||||||
|
config()->set("GUI/EntrySearchColumnSizes", intListToVariant(m_columnSizesSearch));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||||
|
{
|
||||||
|
if (m_activeDbWidget) {
|
||||||
|
disconnect(m_activeDbWidget, 0, this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_activeDbWidget = dbWidget;
|
||||||
|
|
||||||
|
if (m_activeDbWidget) {
|
||||||
|
m_blockUpdates = true;
|
||||||
|
|
||||||
|
if (!m_splitterSizes.isEmpty()) {
|
||||||
|
m_activeDbWidget->setSplitterSizes(m_splitterSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_activeDbWidget->isGroupSelected()) {
|
||||||
|
restoreListView();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
restoreSearchView();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_blockUpdates = false;
|
||||||
|
|
||||||
|
connect(m_activeDbWidget, SIGNAL(splitterSizesChanged()),
|
||||||
|
SLOT(updateSplitterSizes()));
|
||||||
|
connect(m_activeDbWidget, SIGNAL(entryColumnSizesChanged()),
|
||||||
|
SLOT(updateColumnSizes()));
|
||||||
|
connect(m_activeDbWidget, SIGNAL(listModeActivated()),
|
||||||
|
SLOT(restoreListView()));
|
||||||
|
connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
|
||||||
|
SLOT(restoreSearchView()));
|
||||||
|
connect(m_activeDbWidget, SIGNAL(listModeAboutToActivate()),
|
||||||
|
SLOT(blockUpdates()));
|
||||||
|
connect(m_activeDbWidget, SIGNAL(searchModeAboutToActivate()),
|
||||||
|
SLOT(blockUpdates()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::restoreListView()
|
||||||
|
{
|
||||||
|
if (!m_columnSizesList.isEmpty()) {
|
||||||
|
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesList);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_blockUpdates = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::restoreSearchView()
|
||||||
|
{
|
||||||
|
if (!m_columnSizesSearch.isEmpty()) {
|
||||||
|
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_blockUpdates = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::blockUpdates()
|
||||||
|
{
|
||||||
|
m_blockUpdates = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::updateSplitterSizes()
|
||||||
|
{
|
||||||
|
if (m_blockUpdates) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_splitterSizes = m_activeDbWidget->splitterSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWidgetStateSync::updateColumnSizes()
|
||||||
|
{
|
||||||
|
if (m_blockUpdates) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_activeDbWidget->isGroupSelected()) {
|
||||||
|
m_columnSizesList = m_activeDbWidget->entryHeaderViewSizes();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_columnSizesSearch = m_activeDbWidget->entryHeaderViewSizes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> DatabaseWidgetStateSync::variantToIntList(const QVariant& variant)
|
||||||
|
{
|
||||||
|
QVariantList list = variant.toList();
|
||||||
|
QList<int> result;
|
||||||
|
|
||||||
|
Q_FOREACH (const QVariant& var, list) {
|
||||||
|
bool ok;
|
||||||
|
int size = var.toInt(&ok);
|
||||||
|
if (ok) {
|
||||||
|
result.append(size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DatabaseWidgetStateSync::intListToVariant(const QList<int>& list)
|
||||||
|
{
|
||||||
|
QVariantList result;
|
||||||
|
|
||||||
|
Q_FOREACH (int value, list) {
|
||||||
|
result.append(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
54
src/gui/DatabaseWidgetStateSync.h
Normal file
54
src/gui/DatabaseWidgetStateSync.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_HEADERVIEWSYNC_H
|
||||||
|
#define KEEPASSX_HEADERVIEWSYNC_H
|
||||||
|
|
||||||
|
#include "gui/DatabaseWidget.h"
|
||||||
|
|
||||||
|
class DatabaseWidgetStateSync : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DatabaseWidgetStateSync(QObject* parent = Q_NULLPTR);
|
||||||
|
~DatabaseWidgetStateSync();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setActive(DatabaseWidget* dbWidget);
|
||||||
|
void restoreListView();
|
||||||
|
void restoreSearchView();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void blockUpdates();
|
||||||
|
void updateSplitterSizes();
|
||||||
|
void updateColumnSizes();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QList<int> variantToIntList(const QVariant& variant);
|
||||||
|
static QVariant intListToVariant(const QList<int>& list);
|
||||||
|
|
||||||
|
DatabaseWidget* m_activeDbWidget;
|
||||||
|
|
||||||
|
bool m_blockUpdates;
|
||||||
|
QList<int> m_splitterSizes;
|
||||||
|
QList<int> m_columnSizesList;
|
||||||
|
QList<int> m_columnSizesSearch;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_HEADERVIEWSYNC_H
|
@ -194,8 +194,7 @@ void EditWidgetIcons::removeCustomIcon()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MessageBox::information(this, tr("Can't delete icon!"),
|
MessageBox::information(this, tr("Can't delete icon!"),
|
||||||
tr("Can't delete icon. Still used by %1 items.")
|
tr("Can't delete icon. Still used by %n item(s).", 0, iconUsedCount));
|
||||||
.arg(iconUsedCount));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ void KeePass1OpenWidget::openDatabase()
|
|||||||
Q_EMIT editFinished(true);
|
Q_EMIT editFinished(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.\n%1")
|
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
|
||||||
.arg(reader.errorString()));
|
.append(reader.errorString()));
|
||||||
m_ui->editPassword->clear();
|
m_ui->editPassword->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,11 @@
|
|||||||
|
|
||||||
#include "autotype/AutoType.h"
|
#include "autotype/AutoType.h"
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
#include "core/Database.h"
|
|
||||||
#include "core/Entry.h"
|
|
||||||
#include "core/FilePath.h"
|
#include "core/FilePath.h"
|
||||||
#include "core/InactivityTimer.h"
|
#include "core/InactivityTimer.h"
|
||||||
#include "core/Metadata.h"
|
#include "core/Metadata.h"
|
||||||
#include "gui/AboutDialog.h"
|
#include "gui/AboutDialog.h"
|
||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
#include "gui/entry/EntryView.h"
|
|
||||||
#include "gui/group/GroupView.h"
|
|
||||||
|
|
||||||
const QString MainWindow::BaseWindowTitle = "KeePassX";
|
const QString MainWindow::BaseWindowTitle = "KeePassX";
|
||||||
|
|
||||||
@ -40,7 +36,9 @@ MainWindow::MainWindow()
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
restoreGeometry(config()->get("window/Geometry").toByteArray());
|
m_countDefaultAttributes = m_ui->menuEntryCopyAttribute->actions().size();
|
||||||
|
|
||||||
|
restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray());
|
||||||
|
|
||||||
setWindowIcon(filePath()->applicationIcon());
|
setWindowIcon(filePath()->applicationIcon());
|
||||||
QAction* toggleViewAction = m_ui->toolBar->toggleViewAction();
|
QAction* toggleViewAction = m_ui->toolBar->toggleViewAction();
|
||||||
@ -229,17 +227,16 @@ void MainWindow::updateCopyAttributesMenu()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry* entry = dbWidget->entryView()->currentEntry();
|
if (!dbWidget->numberOfSelectedEntries() == 1) {
|
||||||
if (!entry || !dbWidget->entryView()->isSingleEntrySelected()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> actions = m_ui->menuEntryCopyAttribute->actions();
|
QList<QAction*> actions = m_ui->menuEntryCopyAttribute->actions();
|
||||||
for (int i = EntryAttributes::DefaultAttributes.size() + 1; i < actions.size(); i++) {
|
for (int i = m_countDefaultAttributes + 1; i < actions.size(); i++) {
|
||||||
delete actions[i];
|
delete actions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (const QString& key, entry->attributes()->customKeys()) {
|
Q_FOREACH (const QString& key, dbWidget->customEntryAttributes()) {
|
||||||
QAction* action = m_ui->menuEntryCopyAttribute->addAction(key);
|
QAction* action = m_ui->menuEntryCopyAttribute->addAction(key);
|
||||||
m_copyAdditionalAttributeActions->addAction(action);
|
m_copyAdditionalAttributeActions->addAction(action);
|
||||||
}
|
}
|
||||||
@ -276,9 +273,9 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DatabaseWidget::ViewMode: {
|
case DatabaseWidget::ViewMode: {
|
||||||
bool inSearch = dbWidget->isInSearchMode();
|
bool inSearch = dbWidget->isInSearchMode();
|
||||||
bool singleEntrySelected = dbWidget->entryView()->isSingleEntrySelected();
|
bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1;
|
||||||
bool entriesSelected = !dbWidget->entryView()->selectionModel()->selectedRows().isEmpty();
|
bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0;
|
||||||
bool groupSelected = dbWidget->groupView()->currentGroup();
|
bool groupSelected = dbWidget->isGroupSelected();
|
||||||
|
|
||||||
m_ui->actionEntryNew->setEnabled(!inSearch);
|
m_ui->actionEntryNew->setEnabled(!inSearch);
|
||||||
m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inSearch);
|
m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inSearch);
|
||||||
@ -294,7 +291,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||||||
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected);
|
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected);
|
||||||
m_ui->actionGroupNew->setEnabled(groupSelected);
|
m_ui->actionGroupNew->setEnabled(groupSelected);
|
||||||
m_ui->actionGroupEdit->setEnabled(groupSelected);
|
m_ui->actionGroupEdit->setEnabled(groupSelected);
|
||||||
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGoup());
|
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
|
||||||
m_ui->actionSearch->setEnabled(true);
|
m_ui->actionSearch->setEnabled(true);
|
||||||
// TODO: get checked state from db widget
|
// TODO: get checked state from db widget
|
||||||
m_ui->actionSearch->setChecked(inSearch);
|
m_ui->actionSearch->setChecked(inSearch);
|
||||||
@ -313,6 +310,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||||||
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
||||||
action->setEnabled(false);
|
action->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
m_ui->actionEntryCopyTitle->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyUsername->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyPassword->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyURL->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyNotes->setEnabled(false);
|
||||||
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
||||||
|
|
||||||
m_ui->actionSearch->setEnabled(false);
|
m_ui->actionSearch->setEnabled(false);
|
||||||
@ -335,6 +337,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||||||
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
||||||
action->setEnabled(false);
|
action->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
m_ui->actionEntryCopyTitle->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyUsername->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyPassword->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyURL->setEnabled(false);
|
||||||
|
m_ui->actionEntryCopyNotes->setEnabled(false);
|
||||||
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
||||||
|
|
||||||
m_ui->actionSearch->setEnabled(false);
|
m_ui->actionSearch->setEnabled(false);
|
||||||
@ -430,7 +437,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
|||||||
|
|
||||||
void MainWindow::saveWindowInformation()
|
void MainWindow::saveWindowInformation()
|
||||||
{
|
{
|
||||||
config()->set("window/Geometry", saveGeometry());
|
config()->set("GUI/MainWindowGeometry", saveGeometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::saveLastDatabases()
|
bool MainWindow::saveLastDatabases()
|
||||||
|
@ -77,6 +77,7 @@ private:
|
|||||||
QActionGroup* m_copyAdditionalAttributeActions;
|
QActionGroup* m_copyAdditionalAttributeActions;
|
||||||
QStringList m_openDatabases;
|
QStringList m_openDatabases;
|
||||||
InactivityTimer* m_inactivityTimer;
|
InactivityTimer* m_inactivityTimer;
|
||||||
|
int m_countDefaultAttributes;
|
||||||
|
|
||||||
Q_DISABLE_COPY(MainWindow)
|
Q_DISABLE_COPY(MainWindow)
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
<string>Upper Case Letters</string>
|
<string>Upper Case Letters</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>A-Z</string>
|
<string notr="true">A-Z</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@ -116,7 +116,7 @@
|
|||||||
<string>Lower Case Letters</string>
|
<string>Lower Case Letters</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>a-z</string>
|
<string notr="true">a-z</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
<string>Numbers</string>
|
<string>Numbers</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>0-9</string>
|
<string notr="true">0-9</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@ -148,7 +148,7 @@
|
|||||||
<string>Special Characters</string>
|
<string>Special Characters</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>/*_& ...</string>
|
<string notr="true">/*_& ...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -11,7 +11,16 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<property name="margin">
|
<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>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
@ -21,6 +30,9 @@
|
|||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="closeSearchButton">
|
<widget class="QToolButton" name="closeSearchButton">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::ClickFocus</enum>
|
||||||
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -38,7 +50,16 @@
|
|||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QWidget" name="optionsWidget" native="true">
|
<widget class="QWidget" name="optionsWidget" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="margin">
|
<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>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "autotype/AutoType.h"
|
#include "autotype/AutoType.h"
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
|
#include "core/Translator.h"
|
||||||
|
|
||||||
SettingsWidget::SettingsWidget(QWidget* parent)
|
SettingsWidget::SettingsWidget(QWidget* parent)
|
||||||
: EditWidget(parent)
|
: EditWidget(parent)
|
||||||
@ -67,6 +68,16 @@ void SettingsWidget::loadSettings()
|
|||||||
m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool());
|
m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool());
|
||||||
m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool());
|
m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool());
|
||||||
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
|
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
|
||||||
|
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > languages = Translator::availableLanguages();
|
||||||
|
for (int i = 0; i < languages.size(); i++) {
|
||||||
|
m_generalUi->languageComboBox->addItem(languages[i].second, languages[i].first);
|
||||||
|
}
|
||||||
|
int defaultIndex = m_generalUi->languageComboBox->findData(config()->get("GUI/Language"));
|
||||||
|
if (defaultIndex > 0) {
|
||||||
|
m_generalUi->languageComboBox->setCurrentIndex(defaultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if (autoType()->isAvailable()) {
|
if (autoType()->isAvailable()) {
|
||||||
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
|
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
|
||||||
@ -102,6 +113,10 @@ void SettingsWidget::saveSettings()
|
|||||||
config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked());
|
config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked());
|
||||||
config()->set("UseGroupIconOnEntryCreation",
|
config()->set("UseGroupIconOnEntryCreation",
|
||||||
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
|
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
|
||||||
|
config()->set("AutoTypeEntryTitleMatch",
|
||||||
|
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
|
||||||
|
int currentLangIndex = m_generalUi->languageComboBox->currentIndex();
|
||||||
|
config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString());
|
||||||
if (autoType()->isAvailable()) {
|
if (autoType()->isAvailable()) {
|
||||||
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
|
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
|
||||||
config()->set("GlobalAutoTypeModifiers",
|
config()->set("GlobalAutoTypeModifiers",
|
||||||
|
@ -7,10 +7,13 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>456</width>
|
<width>456</width>
|
||||||
<height>185</height>
|
<height>288</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
|
<widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -21,6 +24,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open previous databases on startup</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="modifiedExpandedChangedCheckBox">
|
<widget class="QCheckBox" name="modifiedExpandedChangedCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -31,13 +41,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="autoSaveOnExitCheckBox">
|
<widget class="QCheckBox" name="autoSaveOnExitCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -45,20 +48,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="autoTypeShortcutLabel">
|
<widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Global Auto-Type shortcut</string>
|
<string>Automatically save after every change</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Open previous databases on startup</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -76,6 +69,33 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="autoTypeShortcutLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Global Auto-Type shortcut</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
|
||||||
|
</item>
|
||||||
|
<item row="8" 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="9" column="0">
|
||||||
|
<widget class="QLabel" name="languageLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Language</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QComboBox" name="languageComboBox"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -590,14 +590,14 @@ void EditEntryWidget::insertAttachment()
|
|||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
MessageBox::warning(this, tr("Error"),
|
MessageBox::warning(this, tr("Error"),
|
||||||
tr("Unable to open file:\n").append(file.errorString()));
|
tr("Unable to open file").append(":\n").append(file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
if (!Tools::readAllFromDevice(&file, data)) {
|
if (!Tools::readAllFromDevice(&file, data)) {
|
||||||
MessageBox::warning(this, tr("Error"),
|
MessageBox::warning(this, tr("Error"),
|
||||||
tr("Unable to open file:\n").append(file.errorString()));
|
tr("Unable to open file").append(":\n").append(file.errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,13 +783,13 @@ QMenu* EditEntryWidget::createPresetsMenu()
|
|||||||
QMenu* expirePresetsMenu = new QMenu(this);
|
QMenu* expirePresetsMenu = new QMenu(this);
|
||||||
expirePresetsMenu->addAction(tr("Tomorrow"))->setData(QVariant::fromValue(TimeDelta::fromDays(1)));
|
expirePresetsMenu->addAction(tr("Tomorrow"))->setData(QVariant::fromValue(TimeDelta::fromDays(1)));
|
||||||
expirePresetsMenu->addSeparator();
|
expirePresetsMenu->addSeparator();
|
||||||
expirePresetsMenu->addAction(tr("1 week"))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
|
expirePresetsMenu->addAction(tr("%n week(s)", 0, 1))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
|
||||||
expirePresetsMenu->addAction(tr("2 weeks"))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
|
expirePresetsMenu->addAction(tr("%n week(s)", 0, 2))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
|
||||||
expirePresetsMenu->addAction(tr("3 weeks"))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
|
expirePresetsMenu->addAction(tr("%n week(s)", 0, 3))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
|
||||||
expirePresetsMenu->addSeparator();
|
expirePresetsMenu->addSeparator();
|
||||||
expirePresetsMenu->addAction(tr("1 month"))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
|
expirePresetsMenu->addAction(tr("%n month(s)", 0, 1))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
|
||||||
expirePresetsMenu->addAction(tr("3 months"))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
|
expirePresetsMenu->addAction(tr("%n month(s)", 0, 3))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
|
||||||
expirePresetsMenu->addAction(tr("6 months"))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
|
expirePresetsMenu->addAction(tr("%n month(s)", 0, 6))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
|
||||||
expirePresetsMenu->addSeparator();
|
expirePresetsMenu->addSeparator();
|
||||||
expirePresetsMenu->addAction(tr("1 year"))->setData(QVariant::fromValue(TimeDelta::fromYears(1)));
|
expirePresetsMenu->addAction(tr("1 year"))->setData(QVariant::fromValue(TimeDelta::fromYears(1)));
|
||||||
return expirePresetsMenu;
|
return expirePresetsMenu;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "EntryView.h"
|
#include "EntryView.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
#include "gui/SortFilterHideProxyModel.h"
|
#include "gui/SortFilterHideProxyModel.h"
|
||||||
@ -40,6 +41,7 @@ EntryView::EntryView(QWidget* parent)
|
|||||||
setDragEnabled(true);
|
setDragEnabled(true);
|
||||||
setSortingEnabled(true);
|
setSortingEnabled(true);
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
header()->setDefaultSectionSize(150);
|
||||||
|
|
||||||
// QAbstractItemView::startDrag() uses this property as the default drag action
|
// QAbstractItemView::startDrag() uses this property as the default drag action
|
||||||
setDefaultDropAction(Qt::MoveAction);
|
setDefaultDropAction(Qt::MoveAction);
|
||||||
@ -62,13 +64,24 @@ void EntryView::keyPressEvent(QKeyEvent* event)
|
|||||||
void EntryView::setGroup(Group* group)
|
void EntryView::setGroup(Group* group)
|
||||||
{
|
{
|
||||||
m_model->setGroup(group);
|
m_model->setGroup(group);
|
||||||
Q_EMIT entrySelectionChanged();
|
setFirstEntryActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntryView::setEntryList(const QList<Entry*>& entries)
|
void EntryView::setEntryList(const QList<Entry*>& entries)
|
||||||
{
|
{
|
||||||
m_model->setEntryList(entries);
|
m_model->setEntryList(entries);
|
||||||
Q_EMIT entrySelectionChanged();
|
setFirstEntryActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntryView::setFirstEntryActive()
|
||||||
|
{
|
||||||
|
if(m_model->rowCount() > 0) {
|
||||||
|
QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(0, 0));
|
||||||
|
setCurrentEntry(m_model->entryFromIndex(index));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Q_EMIT entrySelectionChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntryView::inEntryListMode()
|
bool EntryView::inEntryListMode()
|
||||||
@ -100,9 +113,9 @@ Entry* EntryView::currentEntry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntryView::isSingleEntrySelected()
|
int EntryView::numberOfSelectedEntries()
|
||||||
{
|
{
|
||||||
return (selectionModel()->selectedRows().size() == 1);
|
return selectionModel()->selectedRows().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntryView::setCurrentEntry(Entry* entry)
|
void EntryView::setCurrentEntry(Entry* entry)
|
||||||
|
@ -37,11 +37,12 @@ public:
|
|||||||
explicit EntryView(QWidget* parent = Q_NULLPTR);
|
explicit EntryView(QWidget* parent = Q_NULLPTR);
|
||||||
void setModel(QAbstractItemModel* model) Q_DECL_OVERRIDE;
|
void setModel(QAbstractItemModel* model) Q_DECL_OVERRIDE;
|
||||||
Entry* currentEntry();
|
Entry* currentEntry();
|
||||||
bool isSingleEntrySelected();
|
|
||||||
void setCurrentEntry(Entry* entry);
|
void setCurrentEntry(Entry* entry);
|
||||||
Entry* entryFromIndex(const QModelIndex& index);
|
Entry* entryFromIndex(const QModelIndex& index);
|
||||||
void setEntryList(const QList<Entry*>& entries);
|
void setEntryList(const QList<Entry*>& entries);
|
||||||
bool inEntryListMode();
|
bool inEntryListMode();
|
||||||
|
int numberOfSelectedEntries();
|
||||||
|
void setFirstEntryActive();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setGroup(Group* group);
|
void setGroup(Group* group);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
#include "core/qcommandlineparser.h"
|
#include "core/qcommandlineparser.h"
|
||||||
#include "core/Tools.h"
|
#include "core/Tools.h"
|
||||||
|
#include "core/Translator.h"
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
#include "gui/Application.h"
|
#include "gui/Application.h"
|
||||||
#include "gui/MainWindow.h"
|
#include "gui/MainWindow.h"
|
||||||
@ -66,6 +67,8 @@ int main(int argc, char** argv)
|
|||||||
Config::createConfigFromFile(parser.value(configOption));
|
Config::createConfigFromFile(parser.value(configOption));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Translator::installTranslator();
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
// Don't show menu icons on OSX
|
// Don't show menu icons on OSX
|
||||||
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
add_definitions(-DQT_TEST_LIB)
|
add_definitions(-DQT_TEST_LIB)
|
||||||
@ -165,6 +164,12 @@ add_unit_test(NAME testqcommandlineparser SOURCES TestQCommandLineParser.cpp MOC
|
|||||||
add_unit_test(NAME testrandom SOURCES TestRandom.cpp MOCS TestRandom.h
|
add_unit_test(NAME testrandom SOURCES TestRandom.cpp MOCS TestRandom.h
|
||||||
LIBS ${TEST_LIBRARIES})
|
LIBS ${TEST_LIBRARIES})
|
||||||
|
|
||||||
|
add_unit_test(NAME testentrysearcher SOURCES TestEntrySearcher.cpp MOCS TestEntrySearcher.h
|
||||||
|
LIBS ${TEST_LIBRARIES})
|
||||||
|
|
||||||
|
add_unit_test(NAME testexporter SOURCES TestExporter.cpp MOCS TestExporter.h
|
||||||
|
LIBS ${TEST_LIBRARIES})
|
||||||
|
|
||||||
if(WITH_GUI_TESTS)
|
if(WITH_GUI_TESTS)
|
||||||
add_subdirectory(gui)
|
add_subdirectory(gui)
|
||||||
endif(WITH_GUI_TESTS)
|
endif(WITH_GUI_TESTS)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
#include "core/Config.h"
|
||||||
#include "core/FilePath.h"
|
#include "core/FilePath.h"
|
||||||
#include "core/Entry.h"
|
#include "core/Entry.h"
|
||||||
#include "core/Group.h"
|
#include "core/Group.h"
|
||||||
@ -30,11 +31,15 @@
|
|||||||
#include "autotype/test/AutoTypeTestInterface.h"
|
#include "autotype/test/AutoTypeTestInterface.h"
|
||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestAutoType)
|
||||||
|
|
||||||
void TestAutoType::initTestCase()
|
void TestAutoType::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
|
Config::createTempFileInstance();
|
||||||
AutoType::createTestInstance();
|
AutoType::createTestInstance();
|
||||||
|
config()->set("AutoTypeEntryTitleMatch", false);
|
||||||
|
config()->set("security/autotypeask", false);
|
||||||
|
|
||||||
QPluginLoader loader(filePath()->pluginPath("keepassx-autotype-test"));
|
QPluginLoader loader(filePath()->pluginPath("keepassx-autotype-test"));
|
||||||
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
|
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
|
||||||
@ -54,12 +59,24 @@ void TestAutoType::init()
|
|||||||
m_test->clearActions();
|
m_test->clearActions();
|
||||||
|
|
||||||
m_db = new Database();
|
m_db = new Database();
|
||||||
|
m_dbList.clear();
|
||||||
|
m_dbList.append(m_db);
|
||||||
m_group = new Group();
|
m_group = new Group();
|
||||||
m_db->setRootGroup(m_group);
|
m_db->setRootGroup(m_group);
|
||||||
m_entry = new Entry();
|
|
||||||
m_entry->setGroup(m_group);
|
m_entry1 = new Entry();
|
||||||
m_entry->setUsername("myuser");
|
m_entry1->setGroup(m_group);
|
||||||
m_entry->setPassword("mypass");
|
m_entry1->setUsername("myuser");
|
||||||
|
m_entry1->setPassword("mypass");
|
||||||
|
AutoTypeAssociations::Association association;
|
||||||
|
association.window = "custom window";
|
||||||
|
association.sequence = "{username}association{password}";
|
||||||
|
m_entry1->autoTypeAssociations()->add(association);
|
||||||
|
|
||||||
|
m_entry2 = new Entry();
|
||||||
|
m_entry2->setGroup(m_group);
|
||||||
|
m_entry2->setPassword("myuser");
|
||||||
|
m_entry2->setTitle("entry title");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestAutoType::cleanup()
|
void TestAutoType::cleanup()
|
||||||
@ -77,7 +94,7 @@ void TestAutoType::testInternal()
|
|||||||
|
|
||||||
void TestAutoType::testAutoTypeWithoutSequence()
|
void TestAutoType::testAutoTypeWithoutSequence()
|
||||||
{
|
{
|
||||||
m_autoType->performAutoType(m_entry, Q_NULLPTR);
|
m_autoType->performAutoType(m_entry1, Q_NULLPTR);
|
||||||
|
|
||||||
QCOMPARE(m_test->actionCount(), 14);
|
QCOMPARE(m_test->actionCount(), 14);
|
||||||
QCOMPARE(m_test->actionChars(),
|
QCOMPARE(m_test->actionChars(),
|
||||||
@ -88,42 +105,54 @@ void TestAutoType::testAutoTypeWithoutSequence()
|
|||||||
|
|
||||||
void TestAutoType::testAutoTypeWithSequence()
|
void TestAutoType::testAutoTypeWithSequence()
|
||||||
{
|
{
|
||||||
m_autoType->performAutoType(m_entry, Q_NULLPTR, "{Username}abc{PaSsWoRd}");
|
m_autoType->performAutoType(m_entry1, Q_NULLPTR, "{Username}abc{PaSsWoRd}");
|
||||||
|
|
||||||
QCOMPARE(m_test->actionCount(), 15);
|
QCOMPARE(m_test->actionCount(), 15);
|
||||||
QCOMPARE(m_test->actionChars(),
|
QCOMPARE(m_test->actionChars(),
|
||||||
QString("%1abc%2")
|
QString("%1abc%2")
|
||||||
.arg(m_entry->username())
|
.arg(m_entry1->username())
|
||||||
.arg(m_entry->password()));
|
.arg(m_entry1->password()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestAutoType::testGlobalAutoTypeWithNoMatch()
|
void TestAutoType::testGlobalAutoTypeWithNoMatch()
|
||||||
{
|
{
|
||||||
QList<Database*> dbList;
|
m_test->setActiveWindowTitle("nomatch");
|
||||||
dbList.append(m_db);
|
|
||||||
|
|
||||||
MessageBox::setNextAnswer(QMessageBox::Ok);
|
MessageBox::setNextAnswer(QMessageBox::Ok);
|
||||||
m_autoType->performGlobalAutoType(dbList);
|
m_autoType->performGlobalAutoType(m_dbList);
|
||||||
|
|
||||||
QCOMPARE(m_test->actionChars(), QString());
|
QCOMPARE(m_test->actionChars(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestAutoType::testGlobalAutoTypeWithOneMatch()
|
void TestAutoType::testGlobalAutoTypeWithOneMatch()
|
||||||
{
|
{
|
||||||
QList<Database*> dbList;
|
|
||||||
dbList.append(m_db);
|
|
||||||
AutoTypeAssociations::Association association;
|
|
||||||
association.window = "custom window";
|
|
||||||
association.sequence = "{username}association{password}";
|
|
||||||
m_entry->autoTypeAssociations()->add(association);
|
|
||||||
|
|
||||||
m_test->setActiveWindowTitle("custom window");
|
m_test->setActiveWindowTitle("custom window");
|
||||||
m_autoType->performGlobalAutoType(dbList);
|
m_autoType->performGlobalAutoType(m_dbList);
|
||||||
|
|
||||||
QCOMPARE(m_test->actionChars(),
|
QCOMPARE(m_test->actionChars(),
|
||||||
QString("%1association%2")
|
QString("%1association%2")
|
||||||
.arg(m_entry->username())
|
.arg(m_entry1->username())
|
||||||
.arg(m_entry->password()));
|
.arg(m_entry1->password()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestAutoType)
|
void TestAutoType::testGlobalAutoTypeTitleMatch()
|
||||||
|
{
|
||||||
|
config()->set("AutoTypeEntryTitleMatch", true);
|
||||||
|
|
||||||
|
m_test->setActiveWindowTitle("An Entry Title!");
|
||||||
|
m_autoType->performGlobalAutoType(m_dbList);
|
||||||
|
|
||||||
|
QCOMPARE(m_test->actionChars(),
|
||||||
|
QString("%1%2").arg(m_entry2->password(), m_test->keyToString(Qt::Key_Enter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAutoType::testGlobalAutoTypeTitleMatchDisabled()
|
||||||
|
{
|
||||||
|
config()->set("AutoTypeEntryTitleMatch", false);
|
||||||
|
|
||||||
|
m_test->setActiveWindowTitle("An Entry Title!");
|
||||||
|
MessageBox::setNextAnswer(QMessageBox::Ok);
|
||||||
|
m_autoType->performGlobalAutoType(m_dbList);
|
||||||
|
|
||||||
|
QCOMPARE(m_test->actionChars(), QString());
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -41,14 +41,18 @@ private Q_SLOTS:
|
|||||||
void testAutoTypeWithSequence();
|
void testAutoTypeWithSequence();
|
||||||
void testGlobalAutoTypeWithNoMatch();
|
void testGlobalAutoTypeWithNoMatch();
|
||||||
void testGlobalAutoTypeWithOneMatch();
|
void testGlobalAutoTypeWithOneMatch();
|
||||||
|
void testGlobalAutoTypeTitleMatch();
|
||||||
|
void testGlobalAutoTypeTitleMatchDisabled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoTypePlatformInterface* m_platform;
|
AutoTypePlatformInterface* m_platform;
|
||||||
AutoTypeTestInterface* m_test;
|
AutoTypeTestInterface* m_test;
|
||||||
AutoType* m_autoType;
|
AutoType* m_autoType;
|
||||||
Database* m_db;
|
Database* m_db;
|
||||||
|
QList<Database*> m_dbList;
|
||||||
Group* m_group;
|
Group* m_group;
|
||||||
Entry* m_entry;
|
Entry* m_entry1;
|
||||||
|
Entry* m_entry2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_TESTAUTOTYPE_H
|
#endif // KEEPASSX_TESTAUTOTYPE_H
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
#include "crypto/CryptoHash.h"
|
#include "crypto/CryptoHash.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestCryptoHash)
|
||||||
|
|
||||||
void TestCryptoHash::initTestCase()
|
void TestCryptoHash::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -47,5 +49,3 @@ void TestCryptoHash::test()
|
|||||||
QCOMPARE(cryptoHash3.result(),
|
QCOMPARE(cryptoHash3.result(),
|
||||||
QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4"));
|
QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestCryptoHash)
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "format/KeePass2XmlReader.h"
|
#include "format/KeePass2XmlReader.h"
|
||||||
#include "config-keepassx-tests.h"
|
#include "config-keepassx-tests.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestDeletedObjects)
|
||||||
|
|
||||||
void TestDeletedObjects::initTestCase()
|
void TestDeletedObjects::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -158,5 +160,3 @@ void TestDeletedObjects::testDatabaseChange()
|
|||||||
delete db;
|
delete db;
|
||||||
delete db2;
|
delete db2;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestDeletedObjects)
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "core/Entry.h"
|
#include "core/Entry.h"
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestEntry)
|
||||||
|
|
||||||
void TestEntry::initTestCase()
|
void TestEntry::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -121,5 +123,3 @@ void TestEntry::testClone()
|
|||||||
QCOMPARE(entryCloneHistory->historyItems().first()->title(), QString("Original Title"));
|
QCOMPARE(entryCloneHistory->historyItems().first()->title(), QString("Original Title"));
|
||||||
QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
|
QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestEntry)
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "gui/entry/EntryAttachmentsModel.h"
|
#include "gui/entry/EntryAttachmentsModel.h"
|
||||||
#include "gui/entry/EntryAttributesModel.h"
|
#include "gui/entry/EntryAttributesModel.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestEntryModel)
|
||||||
|
|
||||||
void TestEntryModel::initTestCase()
|
void TestEntryModel::initTestCase()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<QModelIndex>("QModelIndex");
|
qRegisterMetaType<QModelIndex>("QModelIndex");
|
||||||
@ -341,5 +343,3 @@ void TestEntryModel::testDatabaseDelete()
|
|||||||
delete modelTest;
|
delete modelTest;
|
||||||
delete model;
|
delete model;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestEntryModel)
|
|
||||||
|
144
tests/TestEntrySearcher.cpp
Normal file
144
tests/TestEntrySearcher.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "TestEntrySearcher.h"
|
||||||
|
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
#include "tests.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestEntrySearcher)
|
||||||
|
|
||||||
|
void TestEntrySearcher::initTestCase()
|
||||||
|
{
|
||||||
|
m_groupRoot = new Group();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestEntrySearcher::cleanupTestCase()
|
||||||
|
{
|
||||||
|
delete m_groupRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestEntrySearcher::testSearch()
|
||||||
|
{
|
||||||
|
Group* group1 = new Group();
|
||||||
|
Group* group2 = new Group();
|
||||||
|
Group* group3 = new Group();
|
||||||
|
|
||||||
|
group1->setParent(m_groupRoot);
|
||||||
|
group2->setParent(m_groupRoot);
|
||||||
|
group3->setParent(m_groupRoot);
|
||||||
|
|
||||||
|
Group* group11 = new Group();
|
||||||
|
|
||||||
|
group11->setParent(group1);
|
||||||
|
|
||||||
|
Group* group21 = new Group();
|
||||||
|
Group* group211 = new Group();
|
||||||
|
Group* group2111 = new Group();
|
||||||
|
|
||||||
|
group21->setParent(group2);
|
||||||
|
group211->setParent(group21);
|
||||||
|
group2111->setParent(group211);
|
||||||
|
|
||||||
|
group1->setSearchingEnabled(Group::Disable);
|
||||||
|
group11->setSearchingEnabled(Group::Enable);
|
||||||
|
|
||||||
|
Entry* eRoot = new Entry();
|
||||||
|
eRoot->setNotes("test search term test");
|
||||||
|
eRoot->setGroup(m_groupRoot);
|
||||||
|
|
||||||
|
Entry* eRoot2 = new Entry();
|
||||||
|
eRoot2->setNotes("test term test");
|
||||||
|
eRoot2->setGroup(m_groupRoot);
|
||||||
|
|
||||||
|
Entry* e1 = new Entry();
|
||||||
|
e1->setNotes("test search term test");
|
||||||
|
e1->setGroup(group1);
|
||||||
|
|
||||||
|
Entry* e11 = new Entry();
|
||||||
|
e11->setNotes("test search term test");
|
||||||
|
e11->setGroup(group11);
|
||||||
|
|
||||||
|
Entry* e2111 = new Entry();
|
||||||
|
e2111->setNotes("test search term test");
|
||||||
|
e2111->setGroup(group2111);
|
||||||
|
|
||||||
|
Entry* e2111b = new Entry();
|
||||||
|
e2111b->setNotes("test search test");
|
||||||
|
e2111b->setGroup(group2111);
|
||||||
|
|
||||||
|
Entry* e3 = new Entry();
|
||||||
|
e3->setNotes("test search term test");
|
||||||
|
e3->setGroup(group3);
|
||||||
|
|
||||||
|
Entry* e3b = new Entry();
|
||||||
|
e3b->setNotes("test search test");
|
||||||
|
e3b->setGroup(group3);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("search term", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 3);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("search term", group211, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("search term", group11, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("search term", group1, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestEntrySearcher::testAndConcatenationInSearch()
|
||||||
|
{
|
||||||
|
Entry* entry = new Entry();
|
||||||
|
entry->setNotes("abc def ghi");
|
||||||
|
entry->setTitle("jkl");
|
||||||
|
entry->setGroup(m_groupRoot);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("def", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search(" abc ghi ", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("ghi ef", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("abc ef xyz", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 0);
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("abc kl", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestEntrySearcher::testAllAttributesAreSearched()
|
||||||
|
{
|
||||||
|
Entry* entry = new Entry();
|
||||||
|
entry->setGroup(m_groupRoot);
|
||||||
|
|
||||||
|
entry->setTitle("testTitle");
|
||||||
|
entry->setUsername("testUsername");
|
||||||
|
entry->setUrl("testUrl");
|
||||||
|
entry->setNotes("testNote");
|
||||||
|
|
||||||
|
m_searchResult = m_entrySearcher.search("testTitle testUsername testUrl testNote", m_groupRoot, Qt::CaseInsensitive);
|
||||||
|
QCOMPARE(m_searchResult.count(), 1);
|
||||||
|
}
|
45
tests/TestEntrySearcher.h
Normal file
45
tests/TestEntrySearcher.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_TESTENTRYSEARCHER_H
|
||||||
|
#define KEEPASSX_TESTENTRYSEARCHER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "core/EntrySearcher.h"
|
||||||
|
#include "core/Group.h"
|
||||||
|
|
||||||
|
class TestEntrySearcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
|
void cleanupTestCase();
|
||||||
|
|
||||||
|
void testAndConcatenationInSearch();
|
||||||
|
void testSearch();
|
||||||
|
void testAllAttributesAreSearched();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Group* m_groupRoot;
|
||||||
|
EntrySearcher m_entrySearcher;
|
||||||
|
QList<Entry*> m_searchResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_TESTENTRYSEARCHER_H
|
82
tests/TestExporter.cpp
Normal file
82
tests/TestExporter.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 "TestExporter.h"
|
||||||
|
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
#include "tests.h"
|
||||||
|
#include "core/ToDbExporter.h"
|
||||||
|
#include "core/Group.h"
|
||||||
|
#include "core/Metadata.h"
|
||||||
|
#include "crypto/Crypto.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestExporter)
|
||||||
|
|
||||||
|
void TestExporter::initTestCase()
|
||||||
|
{
|
||||||
|
Crypto::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestExporter::testToDbExporter()
|
||||||
|
{
|
||||||
|
QImage iconImage(1, 1, QImage::Format_RGB32);
|
||||||
|
iconImage.setPixel(0, 0, qRgb(1, 2, 3));
|
||||||
|
Uuid iconUuid = Uuid::random();
|
||||||
|
|
||||||
|
QImage iconUnusedImage(1, 1, QImage::Format_RGB32);
|
||||||
|
iconUnusedImage.setPixel(0, 0, qRgb(1, 2, 3));
|
||||||
|
Uuid iconUnusedUuid = Uuid::random();
|
||||||
|
|
||||||
|
Database* dbOrg = new Database();
|
||||||
|
Group* groupOrg = new Group();
|
||||||
|
groupOrg->setParent(dbOrg->rootGroup());
|
||||||
|
groupOrg->setName("GTEST");
|
||||||
|
Entry* entryOrg = new Entry();
|
||||||
|
entryOrg->setGroup(groupOrg);
|
||||||
|
entryOrg->setTitle("ETEST");
|
||||||
|
dbOrg->metadata()->addCustomIcon(iconUuid, iconImage);
|
||||||
|
dbOrg->metadata()->addCustomIcon(iconUnusedUuid, iconUnusedImage);
|
||||||
|
entryOrg->setIcon(iconUuid);
|
||||||
|
entryOrg->beginUpdate();
|
||||||
|
entryOrg->setIcon(Entry::DefaultIconNumber);
|
||||||
|
entryOrg->endUpdate();
|
||||||
|
|
||||||
|
Database* dbExp = ToDbExporter().exportGroup(groupOrg);
|
||||||
|
|
||||||
|
QCOMPARE(dbExp->rootGroup()->children().size(), 1);
|
||||||
|
Group* groupExp = dbExp->rootGroup()->children().first();
|
||||||
|
QVERIFY(groupExp != groupOrg);
|
||||||
|
QCOMPARE(groupExp->name(), groupOrg->name());
|
||||||
|
QCOMPARE(groupExp->entries().size(), 1);
|
||||||
|
|
||||||
|
Entry* entryExp = groupExp->entries().first();
|
||||||
|
QCOMPARE(entryExp->title(), entryOrg->title());
|
||||||
|
QCOMPARE(dbExp->metadata()->customIcons().size(), 1);
|
||||||
|
QVERIFY(dbExp->metadata()->containsCustomIcon(iconUuid));
|
||||||
|
QCOMPARE(entryExp->iconNumber(), entryOrg->iconNumber());
|
||||||
|
|
||||||
|
QCOMPARE(entryExp->historyItems().size(), 1);
|
||||||
|
QCOMPARE(entryExp->historyItems().first()->iconUuid(), iconUuid);
|
||||||
|
|
||||||
|
delete dbOrg;
|
||||||
|
delete dbExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
33
tests/TestExporter.h
Normal file
33
tests/TestExporter.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEEPASSX_TESTEXPORTER_H
|
||||||
|
#define KEEPASSX_TESTEXPORTER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class TestExporter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
|
void testToDbExporter();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_TESTEXPORTER_H
|
@ -27,6 +27,8 @@
|
|||||||
#include "core/Metadata.h"
|
#include "core/Metadata.h"
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestGroup)
|
||||||
|
|
||||||
void TestGroup::initTestCase()
|
void TestGroup::initTestCase()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<Entry*>("Entry*");
|
qRegisterMetaType<Entry*>("Entry*");
|
||||||
@ -334,102 +336,6 @@ void TestGroup::testCopyCustomIcon()
|
|||||||
delete dbTarget;
|
delete dbTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGroup::testSearch()
|
|
||||||
{
|
|
||||||
Group* groupRoot = new Group();
|
|
||||||
Group* group1 = new Group();
|
|
||||||
Group* group2 = new Group();
|
|
||||||
Group* group3 = new Group();
|
|
||||||
|
|
||||||
group1->setParent(groupRoot);
|
|
||||||
group2->setParent(groupRoot);
|
|
||||||
group3->setParent(groupRoot);
|
|
||||||
|
|
||||||
Group* group11 = new Group();
|
|
||||||
|
|
||||||
group11->setParent(group1);
|
|
||||||
|
|
||||||
Group* group21 = new Group();
|
|
||||||
Group* group211 = new Group();
|
|
||||||
Group* group2111 = new Group();
|
|
||||||
|
|
||||||
group21->setParent(group2);
|
|
||||||
group211->setParent(group21);
|
|
||||||
group2111->setParent(group211);
|
|
||||||
|
|
||||||
group1->setSearchingEnabled(Group::Disable);
|
|
||||||
group11->setSearchingEnabled(Group::Enable);
|
|
||||||
|
|
||||||
Entry* eRoot = new Entry();
|
|
||||||
eRoot->setNotes("test search term test");
|
|
||||||
eRoot->setGroup(groupRoot);
|
|
||||||
|
|
||||||
Entry* eRoot2 = new Entry();
|
|
||||||
eRoot2->setNotes("test term test");
|
|
||||||
eRoot2->setGroup(groupRoot);
|
|
||||||
|
|
||||||
Entry* e1 = new Entry();
|
|
||||||
e1->setNotes("test search term test");
|
|
||||||
e1->setGroup(group1);
|
|
||||||
|
|
||||||
Entry* e2111 = new Entry();
|
|
||||||
e2111->setNotes("test search term test");
|
|
||||||
e2111->setGroup(group2111);
|
|
||||||
|
|
||||||
Entry* e2111b = new Entry();
|
|
||||||
e2111b->setNotes("test search test");
|
|
||||||
e2111b->setGroup(group2111);
|
|
||||||
|
|
||||||
Entry* e3 = new Entry();
|
|
||||||
e3->setNotes("test search term test");
|
|
||||||
e3->setGroup(group3);
|
|
||||||
|
|
||||||
Entry* e3b = new Entry();
|
|
||||||
e3b->setNotes("test search test");
|
|
||||||
e3b->setGroup(group3);
|
|
||||||
|
|
||||||
QList<Entry*> searchResult;
|
|
||||||
|
|
||||||
searchResult = groupRoot->search("search term", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 3);
|
|
||||||
|
|
||||||
searchResult = group211->search("search term", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
delete groupRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestGroup::testAndConcatenationInSearch()
|
|
||||||
{
|
|
||||||
Group* group = new Group();
|
|
||||||
Entry* entry = new Entry();
|
|
||||||
entry->setNotes("abc def ghi");
|
|
||||||
entry->setTitle("jkl");
|
|
||||||
entry->setGroup(group);
|
|
||||||
|
|
||||||
QList<Entry*> searchResult;
|
|
||||||
|
|
||||||
searchResult = group->search("", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
searchResult = group->search("def", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
searchResult = group->search(" abc ghi ", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
searchResult = group->search("ghi ef", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
searchResult = group->search("abc ef xyz", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 0);
|
|
||||||
|
|
||||||
searchResult = group->search("abc kl", Qt::CaseInsensitive);
|
|
||||||
QCOMPARE(searchResult.count(), 1);
|
|
||||||
|
|
||||||
delete group;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestGroup::testClone()
|
void TestGroup::testClone()
|
||||||
{
|
{
|
||||||
Database* db = new Database();
|
Database* db = new Database();
|
||||||
@ -536,49 +442,3 @@ void TestGroup::testCopyCustomIcons()
|
|||||||
QCOMPARE(metaTarget->customIcon(group1Icon).pixel(0, 0), qRgb(1, 2, 3));
|
QCOMPARE(metaTarget->customIcon(group1Icon).pixel(0, 0), qRgb(1, 2, 3));
|
||||||
QCOMPARE(metaTarget->customIcon(group2Icon).pixel(0, 0), qRgb(4, 5, 6));
|
QCOMPARE(metaTarget->customIcon(group2Icon).pixel(0, 0), qRgb(4, 5, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGroup::testExportToDb()
|
|
||||||
{
|
|
||||||
QImage iconImage(1, 1, QImage::Format_RGB32);
|
|
||||||
iconImage.setPixel(0, 0, qRgb(1, 2, 3));
|
|
||||||
Uuid iconUuid = Uuid::random();
|
|
||||||
|
|
||||||
QImage iconUnusedImage(1, 1, QImage::Format_RGB32);
|
|
||||||
iconUnusedImage.setPixel(0, 0, qRgb(1, 2, 3));
|
|
||||||
Uuid iconUnusedUuid = Uuid::random();
|
|
||||||
|
|
||||||
Database* dbOrg = new Database();
|
|
||||||
Group* groupOrg = new Group();
|
|
||||||
groupOrg->setParent(dbOrg->rootGroup());
|
|
||||||
groupOrg->setName("GTEST");
|
|
||||||
Entry* entryOrg = new Entry();
|
|
||||||
entryOrg->setGroup(groupOrg);
|
|
||||||
entryOrg->setTitle("ETEST");
|
|
||||||
dbOrg->metadata()->addCustomIcon(iconUuid, iconImage);
|
|
||||||
dbOrg->metadata()->addCustomIcon(iconUnusedUuid, iconUnusedImage);
|
|
||||||
entryOrg->setIcon(iconUuid);
|
|
||||||
entryOrg->beginUpdate();
|
|
||||||
entryOrg->setIcon(Entry::DefaultIconNumber);
|
|
||||||
entryOrg->endUpdate();
|
|
||||||
|
|
||||||
Database* dbExp = groupOrg->exportToDb();
|
|
||||||
QCOMPARE(dbExp->rootGroup()->children().size(), 1);
|
|
||||||
Group* groupExp = dbExp->rootGroup()->children().first();
|
|
||||||
QVERIFY(groupExp != groupOrg);
|
|
||||||
QCOMPARE(groupExp->name(), groupOrg->name());
|
|
||||||
QCOMPARE(groupExp->entries().size(), 1);
|
|
||||||
|
|
||||||
Entry* entryExp = groupExp->entries().first();
|
|
||||||
QCOMPARE(entryExp->title(), entryOrg->title());
|
|
||||||
QCOMPARE(dbExp->metadata()->customIcons().size(), 1);
|
|
||||||
QVERIFY(dbExp->metadata()->containsCustomIcon(iconUuid));
|
|
||||||
QCOMPARE(entryExp->iconNumber(), entryOrg->iconNumber());
|
|
||||||
|
|
||||||
QCOMPARE(entryExp->historyItems().size(), 1);
|
|
||||||
QCOMPARE(entryExp->historyItems().first()->iconUuid(), iconUuid);
|
|
||||||
|
|
||||||
delete dbOrg;
|
|
||||||
delete dbExp;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestGroup)
|
|
||||||
|
@ -31,11 +31,8 @@ private Q_SLOTS:
|
|||||||
void testEntries();
|
void testEntries();
|
||||||
void testDeleteSignals();
|
void testDeleteSignals();
|
||||||
void testCopyCustomIcon();
|
void testCopyCustomIcon();
|
||||||
void testSearch();
|
|
||||||
void testAndConcatenationInSearch();
|
|
||||||
void testClone();
|
void testClone();
|
||||||
void testCopyCustomIcons();
|
void testCopyCustomIcons();
|
||||||
void testExportToDb();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_TESTGROUP_H
|
#endif // KEEPASSX_TESTGROUP_H
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
#include "gui/group/GroupModel.h"
|
#include "gui/group/GroupModel.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestGroupModel)
|
||||||
|
|
||||||
void TestGroupModel::initTestCase()
|
void TestGroupModel::initTestCase()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<QModelIndex>("QModelIndex");
|
qRegisterMetaType<QModelIndex>("QModelIndex");
|
||||||
@ -149,5 +151,3 @@ void TestGroupModel::test()
|
|||||||
delete modelTest;
|
delete modelTest;
|
||||||
delete model;
|
delete model;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestGroupModel)
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
#include "streams/HashedBlockStream.h"
|
#include "streams/HashedBlockStream.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestHashedBlockStream)
|
||||||
|
|
||||||
void TestHashedBlockStream::initTestCase()
|
void TestHashedBlockStream::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -69,5 +71,3 @@ void TestHashedBlockStream::testWriteRead()
|
|||||||
buffer.reset();
|
buffer.reset();
|
||||||
buffer.buffer().clear();
|
buffer.buffer().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestHashedBlockStream)
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "keys/FileKey.h"
|
#include "keys/FileKey.h"
|
||||||
#include "keys/PasswordKey.h"
|
#include "keys/PasswordKey.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeePass1Reader)
|
||||||
|
|
||||||
void TestKeePass1Reader::initTestCase()
|
void TestKeePass1Reader::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -292,5 +294,3 @@ void TestKeePass1Reader::reopenDatabase(Database* db, const QString& password, c
|
|||||||
QVERIFY(!reader.hasError());
|
QVERIFY(!reader.hasError());
|
||||||
delete newDb;
|
delete newDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeePass1Reader)
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "format/KeePass2.h"
|
#include "format/KeePass2.h"
|
||||||
#include "format/KeePass2RandomStream.h"
|
#include "format/KeePass2RandomStream.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeePass2RandomStream)
|
||||||
|
|
||||||
void TestKeePass2RandomStream::initTestCase()
|
void TestKeePass2RandomStream::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -77,5 +79,3 @@ void TestKeePass2RandomStream::test()
|
|||||||
QCOMPARE(cipherData, cipherDataEncrypt);
|
QCOMPARE(cipherData, cipherDataEncrypt);
|
||||||
QCOMPARE(randomStreamData, cipherData);
|
QCOMPARE(randomStreamData, cipherData);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeePass2RandomStream)
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "format/KeePass2Reader.h"
|
#include "format/KeePass2Reader.h"
|
||||||
#include "keys/PasswordKey.h"
|
#include "keys/PasswordKey.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeePass2Reader)
|
||||||
|
|
||||||
void TestKeePass2Reader::initTestCase()
|
void TestKeePass2Reader::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -154,5 +156,3 @@ void TestKeePass2Reader::testFormat300()
|
|||||||
|
|
||||||
delete db;
|
delete db;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeePass2Reader)
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "format/KeePass2Writer.h"
|
#include "format/KeePass2Writer.h"
|
||||||
#include "keys/PasswordKey.h"
|
#include "keys/PasswordKey.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeePass2Writer)
|
||||||
|
|
||||||
void TestKeePass2Writer::initTestCase()
|
void TestKeePass2Writer::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -104,5 +106,3 @@ void TestKeePass2Writer::cleanupTestCase()
|
|||||||
delete m_dbOrg;
|
delete m_dbOrg;
|
||||||
delete m_dbTest;
|
delete m_dbTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeePass2Writer)
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "format/KeePass2XmlReader.h"
|
#include "format/KeePass2XmlReader.h"
|
||||||
#include "config-keepassx-tests.h"
|
#include "config-keepassx-tests.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeePass2XmlReader)
|
||||||
|
|
||||||
namespace QTest {
|
namespace QTest {
|
||||||
template<>
|
template<>
|
||||||
char* toString(const Uuid& uuid)
|
char* toString(const Uuid& uuid)
|
||||||
@ -378,5 +380,3 @@ void TestKeePass2XmlReader::cleanupTestCase()
|
|||||||
{
|
{
|
||||||
delete m_db;
|
delete m_db;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeePass2XmlReader)
|
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "keys/FileKey.h"
|
#include "keys/FileKey.h"
|
||||||
#include "keys/PasswordKey.h"
|
#include "keys/PasswordKey.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestKeys)
|
||||||
|
|
||||||
void TestKeys::initTestCase()
|
void TestKeys::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -184,5 +186,3 @@ void TestKeys::benchmarkTransformKey()
|
|||||||
compositeKey.transform(seed, 1e6);
|
compositeKey.transform(seed, 1e6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestKeys)
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "core/Tools.h"
|
#include "core/Tools.h"
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestModified)
|
||||||
|
|
||||||
void TestModified::initTestCase()
|
void TestModified::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -466,5 +468,3 @@ void TestModified::testHistoryItem()
|
|||||||
|
|
||||||
delete db;
|
delete db;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestModified)
|
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "core/qcommandlineparser.h"
|
#include "core/qcommandlineparser.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestQCommandLineParser)
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(char**)
|
Q_DECLARE_METATYPE(char**)
|
||||||
|
|
||||||
static char *empty_argv[] = { 0 };
|
static char *empty_argv[] = { 0 };
|
||||||
@ -412,5 +414,3 @@ void TestQCommandLineParser::testSingleDashWordOptionModes()
|
|||||||
QCOMPARE(parser.value(parser.optionNames().at(i)), expectedOptionValues.at(i));
|
QCOMPARE(parser.value(parser.optionNames().at(i)), expectedOptionValues.at(i));
|
||||||
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestQCommandLineParser)
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "core/qsavefile.h"
|
#include "core/qsavefile.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestQSaveFile)
|
||||||
|
|
||||||
class DirCleanup
|
class DirCleanup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -154,6 +156,9 @@ void TestQSaveFile::transactionalWriteCanceled()
|
|||||||
void TestQSaveFile::transactionalWriteErrorRenaming()
|
void TestQSaveFile::transactionalWriteErrorRenaming()
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
|
if (::geteuid() == 0) {
|
||||||
|
QSKIP("not valid running this test as root", SkipAll);
|
||||||
|
}
|
||||||
const QString dir = tmpDir();
|
const QString dir = tmpDir();
|
||||||
QVERIFY(!dir.isEmpty());
|
QVERIFY(!dir.isEmpty());
|
||||||
const QString targetFile = dir + QString::fromLatin1("/outfile");
|
const QString targetFile = dir + QString::fromLatin1("/outfile");
|
||||||
@ -197,5 +202,3 @@ QString TestQSaveFile::tmpDir()
|
|||||||
|
|
||||||
return dirName;
|
return dirName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestQSaveFile)
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestRandom)
|
||||||
|
|
||||||
void TestRandom::initTestCase()
|
void TestRandom::initTestCase()
|
||||||
{
|
{
|
||||||
m_backend = new RandomBackendTest();
|
m_backend = new RandomBackendTest();
|
||||||
@ -93,5 +95,3 @@ void RandomBackendTest::setNextBytes(const QByteArray& nextBytes)
|
|||||||
m_nextBytes = nextBytes;
|
m_nextBytes = nextBytes;
|
||||||
m_bytesIndex = 0;
|
m_bytesIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestRandom)
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "crypto/SymmetricCipher.h"
|
#include "crypto/SymmetricCipher.h"
|
||||||
#include "streams/SymmetricCipherStream.h"
|
#include "streams/SymmetricCipherStream.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestSymmetricCipher)
|
||||||
|
|
||||||
void TestSymmetricCipher::initTestCase()
|
void TestSymmetricCipher::initTestCase()
|
||||||
{
|
{
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
@ -192,5 +194,3 @@ void TestSymmetricCipher::testPadding()
|
|||||||
QByteArray decrypted = streamDec.readAll();
|
QByteArray decrypted = streamDec.readAll();
|
||||||
QCOMPARE(decrypted, plainText);
|
QCOMPARE(decrypted, plainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestSymmetricCipher)
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "autotype/WildcardMatcher.h"
|
#include "autotype/WildcardMatcher.h"
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestWildcardMatcher)
|
||||||
|
|
||||||
const QString TestWildcardMatcher::DefaultText = QString("some text");
|
const QString TestWildcardMatcher::DefaultText = QString("some text");
|
||||||
const QString TestWildcardMatcher::AlternativeText = QString("some other text");
|
const QString TestWildcardMatcher::AlternativeText = QString("some other text");
|
||||||
|
|
||||||
@ -82,5 +84,3 @@ void TestWildcardMatcher::verifyNoMatch(QString pattern)
|
|||||||
bool matchResult = m_matcher->match(pattern);
|
bool matchResult = m_matcher->match(pattern);
|
||||||
QVERIFY(!matchResult);
|
QVERIFY(!matchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestWildcardMatcher)
|
|
||||||
|
@ -83,7 +83,7 @@ void TestGui::testTabs()
|
|||||||
|
|
||||||
void TestGui::testEditEntry()
|
void TestGui::testEditEntry()
|
||||||
{
|
{
|
||||||
EntryView* entryView = m_dbWidget->entryView();
|
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
|
||||||
QModelIndex item = entryView->model()->index(0, 1);
|
QModelIndex item = entryView->model()->index(0, 1);
|
||||||
QRect itemRect = entryView->visualRect(item);
|
QRect itemRect = entryView->visualRect(item);
|
||||||
QTest::mouseClick(entryView->viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center());
|
QTest::mouseClick(entryView->viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center());
|
||||||
@ -237,8 +237,8 @@ void TestGui::testSearch()
|
|||||||
|
|
||||||
void TestGui::testDeleteEntry()
|
void TestGui::testDeleteEntry()
|
||||||
{
|
{
|
||||||
GroupView* groupView = m_dbWidget->groupView();
|
GroupView* groupView = m_dbWidget->findChild<GroupView*>("groupView");
|
||||||
EntryView* entryView = m_dbWidget->entryView();
|
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
|
||||||
QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
|
QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
|
||||||
QAction* entryDeleteAction = m_mainWindow->findChild<QAction*>("actionEntryDelete");
|
QAction* entryDeleteAction = m_mainWindow->findChild<QAction*>("actionEntryDelete");
|
||||||
QWidget* entryDeleteWidget = toolBar->widgetForAction(entryDeleteAction);
|
QWidget* entryDeleteWidget = toolBar->widgetForAction(entryDeleteAction);
|
||||||
@ -274,7 +274,7 @@ void TestGui::testDeleteEntry()
|
|||||||
|
|
||||||
void TestGui::testCloneEntry()
|
void TestGui::testCloneEntry()
|
||||||
{
|
{
|
||||||
EntryView* entryView = m_dbWidget->entryView();
|
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
|
||||||
|
|
||||||
QCOMPARE(entryView->model()->rowCount(), 1);
|
QCOMPARE(entryView->model()->rowCount(), 1);
|
||||||
|
|
||||||
@ -292,8 +292,8 @@ void TestGui::testCloneEntry()
|
|||||||
|
|
||||||
void TestGui::testDragAndDropEntry()
|
void TestGui::testDragAndDropEntry()
|
||||||
{
|
{
|
||||||
EntryView* entryView = m_dbWidget->entryView();
|
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
|
||||||
GroupView* groupView = m_dbWidget->groupView();
|
GroupView* groupView = m_dbWidget->findChild<GroupView*>("groupView");
|
||||||
QAbstractItemModel* groupModel = groupView->model();
|
QAbstractItemModel* groupModel = groupView->model();
|
||||||
|
|
||||||
QModelIndex sourceIndex = entryView->model()->index(0, 1);
|
QModelIndex sourceIndex = entryView->model()->index(0, 1);
|
||||||
@ -314,7 +314,7 @@ void TestGui::testDragAndDropEntry()
|
|||||||
|
|
||||||
void TestGui::testDragAndDropGroup()
|
void TestGui::testDragAndDropGroup()
|
||||||
{
|
{
|
||||||
QAbstractItemModel* groupModel = m_dbWidget->groupView()->model();
|
QAbstractItemModel* groupModel = m_dbWidget->findChild<GroupView*>("groupView")->model();
|
||||||
QModelIndex rootIndex = groupModel->index(0, 0);
|
QModelIndex rootIndex = groupModel->index(0, 0);
|
||||||
|
|
||||||
dragAndDropGroup(groupModel->index(0, 0, rootIndex),
|
dragAndDropGroup(groupModel->index(0, 0, rootIndex),
|
||||||
@ -453,7 +453,7 @@ void TestGui::dragAndDropGroup(const QModelIndex& sourceIndex, const QModelIndex
|
|||||||
QVERIFY(sourceIndex.isValid());
|
QVERIFY(sourceIndex.isValid());
|
||||||
QVERIFY(targetIndex.isValid());
|
QVERIFY(targetIndex.isValid());
|
||||||
|
|
||||||
GroupModel* groupModel = qobject_cast<GroupModel*>(m_dbWidget->groupView()->model());
|
GroupModel* groupModel = qobject_cast<GroupModel*>(m_dbWidget->findChild<GroupView*>("groupView")->model());
|
||||||
|
|
||||||
QMimeData mimeData;
|
QMimeData mimeData;
|
||||||
QByteArray encoded;
|
QByteArray encoded;
|
||||||
|
Loading…
Reference in New Issue
Block a user