Merge branch 'develop' into feature/allow-disable-app-bundle
89
.clang-format
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterFunction: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
||||
|
2
COPYING
@ -41,6 +41,8 @@ Files: share/icons/application/*/apps/keepassxc.png
|
||||
share/icons/application/scalable/apps/keepassxc-dark.svgz
|
||||
share/icons/application/*/apps/keepassxc-locked.png
|
||||
share/icons/application/scalable/apps/keepassxc-locked.svgz
|
||||
share/icons/application/*/apps/keepassxc-unlocked.png
|
||||
share/icons/application/scalable/apps/keepassxc-unlocked.svgz
|
||||
share/icons/application/*/mimetypes/application-x-keepassxc.png
|
||||
share/icons/application/scalable/mimetypes/application-x-keepassxc.svgz
|
||||
Copyright: 2016, Lorenzo Stella <lorenzo.stl@gmail.com>
|
||||
|
@ -27,7 +27,7 @@ Pre-compiled binaries can be found on the [downloads page](https://keepassxc.org
|
||||
|
||||
### Building KeePassXC
|
||||
|
||||
*More detailed instructions are available in the INSTALL file or on the [Wiki page](https://github.com/keepassxreboot/keepassx/wiki/Install-Instruction-from-Source).*
|
||||
*More detailed instructions are available in the INSTALL file or on the [Wiki page](https://github.com/keepassxreboot/keepassxc/wiki/Building-KeePassXC).*
|
||||
|
||||
First, you must download the KeePassXC [source tarball](https://keepassxc.org/download#source) or check out the latest version from our [Git repository](https://github.com/keepassxreboot/keepassxc).
|
||||
|
||||
|
@ -89,6 +89,22 @@ add_custom_target(icons
|
||||
COMMAND inkscape -z -w 256 -h 256
|
||||
icons/application/scalable/apps/keepassxc-locked.svgz -e icons/application/256x256/apps/keepassxc-locked.png
|
||||
|
||||
# SVGZ to PNGs for KeePassXC
|
||||
COMMAND inkscape -z -w 16 -h 16
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/16x16/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 24 -h 24
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/24x24/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 32 -h 32
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/32x32/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 48 -h 48
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/48x48/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 64 -h 64
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/64x64/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 128 -h 128
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/128x128/apps/keepassxc-unlocked.png
|
||||
COMMAND inkscape -z -w 256 -h 256
|
||||
icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/256x256/apps/keepassxc-unlocked.png
|
||||
|
||||
# SVGZ to PNGs for KeePassXC MIME-Type
|
||||
COMMAND inkscape -z -w 16 -h 16
|
||||
icons/application/scalable/mimetypes/application-x-keepassxc.svgz -e icons/application/16x16/mimetypes/application-x-keepassxc.png
|
||||
|
BIN
share/icons/application/128x128/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
share/icons/application/16x16/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 880 B |
BIN
share/icons/application/24x24/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
share/icons/application/256x256/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
share/icons/application/32x32/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
share/icons/application/48x48/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
share/icons/application/64x64/apps/keepassxc-unlocked.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
share/icons/application/scalable/apps/keepassxc-unlocked.svgz
Normal file
@ -574,8 +574,9 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
|
||||
}
|
||||
}
|
||||
|
||||
if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->resolvePlaceholder(entry->title()).isEmpty()
|
||||
&& windowTitle.contains(entry->resolvePlaceholder(entry->title()), Qt::CaseInsensitive)) {
|
||||
if (!match && config()->get("AutoTypeEntryTitleMatch").toBool()
|
||||
&& (windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))
|
||||
|| windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url())))) {
|
||||
sequence = entry->defaultAutoTypeSequence();
|
||||
match = true;
|
||||
}
|
||||
@ -631,3 +632,22 @@ bool AutoType::windowMatches(const QString& windowTitle, const QString& windowPa
|
||||
return WildcardMatcher(windowTitle).match(windowPattern);
|
||||
}
|
||||
}
|
||||
|
||||
bool AutoType::windowMatchesTitle(const QString& windowTitle, const QString& resolvedTitle)
|
||||
{
|
||||
return !resolvedTitle.isEmpty() && windowTitle.contains(resolvedTitle, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resolvedUrl)
|
||||
{
|
||||
if (!resolvedUrl.isEmpty() && windowTitle.contains(resolvedUrl, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QUrl url(resolvedUrl);
|
||||
if (url.isValid() && !url.host().isEmpty()) {
|
||||
return windowTitle.contains(url.host(), Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ private:
|
||||
bool parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions);
|
||||
QList<AutoTypeAction*> createActionFromTemplate(const QString& tmpl, const Entry* entry);
|
||||
QString autoTypeSequence(const Entry* entry, const QString& windowTitle = QString());
|
||||
bool windowMatchesTitle(const QString& windowTitle, const QString& resolvedTitle);
|
||||
bool windowMatchesUrl(const QString& windowTitle, const QString& resolvedUrl);
|
||||
bool windowMatches(const QString& windowTitle, const QString& windowPattern);
|
||||
|
||||
bool m_inAutoType;
|
||||
|
@ -101,7 +101,7 @@ QIcon FilePath::trayIconLocked()
|
||||
|
||||
QIcon FilePath::trayIconUnlocked()
|
||||
{
|
||||
return applicationIcon();
|
||||
return icon("apps", "keepassxc-unlocked");
|
||||
}
|
||||
|
||||
QIcon FilePath::icon(const QString& category, const QString& name, bool fromTheme)
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "core/FilePath.h"
|
||||
|
||||
SearchWidget::SearchWidget(QWidget *parent)
|
||||
SearchWidget::SearchWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::SearchWidget())
|
||||
{
|
||||
@ -40,11 +40,11 @@ SearchWidget::SearchWidget(QWidget *parent)
|
||||
connect(this, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear()));
|
||||
|
||||
new QShortcut(Qt::CTRL + Qt::Key_F, this, SLOT(searchFocus()), nullptr, Qt::ApplicationShortcut);
|
||||
new QShortcut(Qt::Key_Escape, m_ui->searchEdit, SLOT(clear()), nullptr, Qt::ApplicationShortcut);
|
||||
new QShortcut(Qt::Key_Escape, m_ui->searchEdit, SLOT(clear()), nullptr, Qt::ApplicationShortcut);
|
||||
|
||||
m_ui->searchEdit->installEventFilter(this);
|
||||
|
||||
QMenu *searchMenu = new QMenu();
|
||||
QMenu* searchMenu = new QMenu();
|
||||
m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive()));
|
||||
m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive");
|
||||
m_actionCaseSensitive->setCheckable(true);
|
||||
@ -58,39 +58,35 @@ SearchWidget::SearchWidget(QWidget *parent)
|
||||
m_ui->searchEdit->addAction(m_ui->clearIcon, QLineEdit::TrailingPosition);
|
||||
|
||||
// Fix initial visibility of actions (bug in Qt)
|
||||
for (QToolButton * toolButton: m_ui->searchEdit->findChildren<QToolButton *>()) {
|
||||
for (QToolButton* toolButton : m_ui->searchEdit->findChildren<QToolButton*>()) {
|
||||
toolButton->setVisible(toolButton->defaultAction()->isVisible());
|
||||
}
|
||||
}
|
||||
|
||||
SearchWidget::~SearchWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool SearchWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
bool SearchWidget::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Escape) {
|
||||
emit escapePressed();
|
||||
return true;
|
||||
}
|
||||
else if (keyEvent->matches(QKeySequence::Copy)) {
|
||||
} else if (keyEvent->matches(QKeySequence::Copy)) {
|
||||
// If Control+C is pressed in the search edit when no text
|
||||
// is selected, copy the password of the current entry
|
||||
if (!m_ui->searchEdit->hasSelectedText()) {
|
||||
emit copyPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
|
||||
} else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
|
||||
if (m_ui->searchEdit->cursorPosition() == m_ui->searchEdit->text().length()) {
|
||||
// If down is pressed at EOL, move the focus to the entry view
|
||||
emit downPressed();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Otherwise move the cursor to EOL
|
||||
m_ui->searchEdit->setCursorPosition(m_ui->searchEdit->text().length());
|
||||
return true;
|
||||
@ -110,7 +106,7 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
|
||||
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
|
||||
}
|
||||
|
||||
void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
|
||||
void SearchWidget::databaseChanged(DatabaseWidget* dbWidget)
|
||||
{
|
||||
if (dbWidget != nullptr) {
|
||||
// Set current search text from this database
|
||||
|
@ -18,11 +18,11 @@
|
||||
#ifndef KEEPASSX_SEARCHWIDGET_H
|
||||
#define KEEPASSX_SEARCHWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include "gui/DatabaseWidget.h"
|
||||
#include "core/SignalMultiplexer.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class SearchWidget;
|
||||
@ -33,17 +33,17 @@ class SearchWidget : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SearchWidget(QWidget *parent = 0);
|
||||
explicit SearchWidget(QWidget* parent = 0);
|
||||
~SearchWidget();
|
||||
|
||||
void connectSignals(SignalMultiplexer& mx);
|
||||
void setCaseSensitive(bool state);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
bool eventFilter(QObject* obj, QEvent* event);
|
||||
|
||||
signals:
|
||||
void search(const QString &text);
|
||||
void search(const QString& text);
|
||||
void caseSensitiveChanged(bool state);
|
||||
void escapePressed();
|
||||
void copyPressed();
|
||||
@ -62,7 +62,7 @@ private slots:
|
||||
private:
|
||||
const QScopedPointer<Ui::SearchWidget> m_ui;
|
||||
QTimer* m_searchTimer;
|
||||
QAction *m_actionCaseSensitive;
|
||||
QAction* m_actionCaseSensitive;
|
||||
|
||||
Q_DISABLE_COPY(SearchWidget)
|
||||
};
|
||||
|
@ -303,7 +303,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
|
||||
<property name="text">
|
||||
<string>Use entry title to match windows for global Auto-Type</string>
|
||||
<string>Use entry title and URL to match windows for global Auto-Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -104,6 +104,12 @@ void TestAutoType::init()
|
||||
association.window = "//^CustomAttr3$//";
|
||||
association.sequence = "{PaSSworD}";
|
||||
m_entry4->autoTypeAssociations()->add(association);
|
||||
|
||||
m_entry5 = new Entry();
|
||||
m_entry5->setGroup(m_group);
|
||||
m_entry5->setPassword("example5");
|
||||
m_entry5->setTitle("some title");
|
||||
m_entry5->setUrl("http://example.org");
|
||||
}
|
||||
|
||||
void TestAutoType::cleanup()
|
||||
@ -172,6 +178,28 @@ void TestAutoType::testGlobalAutoTypeTitleMatch()
|
||||
QString("%1%2").arg(m_entry2->password(), m_test->keyToString(Qt::Key_Enter)));
|
||||
}
|
||||
|
||||
void TestAutoType::testGlobalAutoTypeUrlMatch()
|
||||
{
|
||||
config()->set("AutoTypeEntryTitleMatch", true);
|
||||
|
||||
m_test->setActiveWindowTitle("Dummy - http://example.org/ - <My Browser>");
|
||||
m_autoType->performGlobalAutoType(m_dbList);
|
||||
|
||||
QCOMPARE(m_test->actionChars(),
|
||||
QString("%1%2").arg(m_entry5->password(), m_test->keyToString(Qt::Key_Enter)));
|
||||
}
|
||||
|
||||
void TestAutoType::testGlobalAutoTypeUrlSubdomainMatch()
|
||||
{
|
||||
config()->set("AutoTypeEntryTitleMatch", true);
|
||||
|
||||
m_test->setActiveWindowTitle("Dummy - http://sub.example.org/ - <My Browser>");
|
||||
m_autoType->performGlobalAutoType(m_dbList);
|
||||
|
||||
QCOMPARE(m_test->actionChars(),
|
||||
QString("%1%2").arg(m_entry5->password(), m_test->keyToString(Qt::Key_Enter)));
|
||||
}
|
||||
|
||||
void TestAutoType::testGlobalAutoTypeTitleMatchDisabled()
|
||||
{
|
||||
m_test->setActiveWindowTitle("An Entry Title!");
|
||||
|
@ -42,6 +42,8 @@ private slots:
|
||||
void testGlobalAutoTypeWithNoMatch();
|
||||
void testGlobalAutoTypeWithOneMatch();
|
||||
void testGlobalAutoTypeTitleMatch();
|
||||
void testGlobalAutoTypeUrlMatch();
|
||||
void testGlobalAutoTypeUrlSubdomainMatch();
|
||||
void testGlobalAutoTypeTitleMatchDisabled();
|
||||
void testGlobalAutoTypeRegExp();
|
||||
|
||||
@ -56,6 +58,7 @@ private:
|
||||
Entry* m_entry2;
|
||||
Entry* m_entry3;
|
||||
Entry* m_entry4;
|
||||
Entry* m_entry5;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TESTAUTOTYPE_H
|
||||
|
20
utils/fix_mac.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Canonical path to qt5 directory
|
||||
QT="/usr/local/Cellar/qt"
|
||||
if [ ! -d "$QT" ]; then
|
||||
# Alternative (old) path to qt5 directory
|
||||
QT+="5"
|
||||
if [ ! -d "$QT" ]; then
|
||||
echo "Qt/Qt5 not found!"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
QT5_DIR="$QT/$(ls $QT | sort -r | head -n1)"
|
||||
echo $QT5_DIR
|
||||
|
||||
# Change qt5 framework ids
|
||||
for framework in $(find "$QT5_DIR/lib" -regex ".*/\(Qt[a-zA-Z]*\)\.framework/Versions/5/\1"); do
|
||||
echo "$framework"
|
||||
install_name_tool -id "$framework" "$framework"
|
||||
done
|