mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-27 00:09:53 -05:00
Show group and entry view context menus from MainWindow.
This allows us to drop the duplicate actions in DatabaseWidget.
This commit is contained in:
parent
15c18dd899
commit
668103a00f
@ -38,6 +38,7 @@ set(keepassx_SOURCES
|
||||
core/ListDeleter.h
|
||||
core/Metadata.cpp
|
||||
core/qsavefile.cpp
|
||||
core/SignalMultiplexer.cpp
|
||||
core/TimeInfo.cpp
|
||||
core/Tools.cpp
|
||||
core/Uuid.cpp
|
||||
|
148
src/core/SignalMultiplexer.cpp
Normal file
148
src/core/SignalMultiplexer.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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 "SignalMultiplexer.h"
|
||||
|
||||
SignalMultiplexer::SignalMultiplexer()
|
||||
{
|
||||
}
|
||||
|
||||
SignalMultiplexer::~SignalMultiplexer()
|
||||
{
|
||||
// disconnect all connections
|
||||
setCurrentObject(Q_NULLPTR);
|
||||
}
|
||||
|
||||
QObject* SignalMultiplexer::currentObject() const
|
||||
{
|
||||
return m_currentObject;
|
||||
}
|
||||
|
||||
void SignalMultiplexer::setCurrentObject(QObject* object)
|
||||
{
|
||||
// remove all Connections from the list whoes senders/receivers have been deleted
|
||||
QMutableListIterator<Connection> i = m_connections;
|
||||
while (i.hasNext()) {
|
||||
const Connection& con = i.next();
|
||||
|
||||
if (!con.sender && !con.receiver) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_currentObject) {
|
||||
Q_FOREACH (const Connection& con, m_connections) {
|
||||
disconnect(con);
|
||||
}
|
||||
}
|
||||
|
||||
m_currentObject = object;
|
||||
|
||||
if (object) {
|
||||
Q_FOREACH (const Connection& con, m_connections) {
|
||||
connect(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::connect(QObject* sender, const char* signal, const char* slot)
|
||||
{
|
||||
Q_ASSERT(sender);
|
||||
|
||||
Connection con;
|
||||
con.slot = slot;
|
||||
con.sender = sender;
|
||||
con.signal = signal;
|
||||
m_connections << con;
|
||||
|
||||
if (m_currentObject) {
|
||||
connect(con);
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::connect(const char* signal, QObject* receiver, const char* slot)
|
||||
{
|
||||
Q_ASSERT(receiver);
|
||||
|
||||
Connection con;
|
||||
con.receiver = receiver;
|
||||
con.signal = signal;
|
||||
con.slot = slot;
|
||||
m_connections << con;
|
||||
|
||||
if (m_currentObject) {
|
||||
connect(con);
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::disconnect(QObject* sender, const char* signal, const char* slot)
|
||||
{
|
||||
Q_ASSERT(sender);
|
||||
|
||||
QMutableListIterator<Connection> i = m_connections;
|
||||
while (i.hasNext()) {
|
||||
const Connection& con = i.next();
|
||||
|
||||
if (con.sender == sender && qstrcmp(con.signal, signal) == 0 && qstrcmp(con.slot, slot) == 0) {
|
||||
if (m_currentObject) {
|
||||
disconnect(con);
|
||||
}
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::disconnect(const char* signal, QObject* receiver, const char* slot)
|
||||
{
|
||||
Q_ASSERT(receiver);
|
||||
|
||||
QMutableListIterator<Connection> i = m_connections;
|
||||
while (i.hasNext()) {
|
||||
const Connection& con = i.next();
|
||||
|
||||
if (con.receiver == receiver && qstrcmp(con.signal, signal) == 0 && qstrcmp(con.slot, slot) == 0) {
|
||||
if (m_currentObject) {
|
||||
disconnect(con);
|
||||
}
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::connect(const Connection& con)
|
||||
{
|
||||
Q_ASSERT(con.sender || con.receiver);
|
||||
|
||||
if (con.sender) {
|
||||
QObject::connect(con.sender, con.signal, m_currentObject, con.slot);
|
||||
}
|
||||
else {
|
||||
QObject::connect(m_currentObject, con.signal, con.receiver, con.slot);
|
||||
}
|
||||
}
|
||||
|
||||
void SignalMultiplexer::disconnect(const Connection& con)
|
||||
{
|
||||
Q_ASSERT(con.sender || con.receiver);
|
||||
|
||||
if (con.sender) {
|
||||
QObject::disconnect(con.sender, con.signal, m_currentObject, con.slot);
|
||||
}
|
||||
else {
|
||||
QObject::disconnect(m_currentObject, con.signal, con.receiver, con.slot);
|
||||
}
|
||||
}
|
58
src/core/SignalMultiplexer.h
Normal file
58
src/core/SignalMultiplexer.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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_SIGNALMULTIPLEXER_H
|
||||
#define KEEPASSX_SIGNALMULTIPLEXER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "core/Global.h"
|
||||
|
||||
class SignalMultiplexer
|
||||
{
|
||||
public:
|
||||
SignalMultiplexer();
|
||||
~SignalMultiplexer();
|
||||
QObject* currentObject() const;
|
||||
void setCurrentObject(QObject* object);
|
||||
|
||||
void connect(QObject* sender, const char* signal, const char* slot);
|
||||
void disconnect(QObject* sender, const char* signal, const char* slot);
|
||||
|
||||
void connect(const char* signal, QObject* receiver, const char* slot);
|
||||
void disconnect(const char* signal, QObject* receiver, const char* slot);
|
||||
|
||||
private:
|
||||
struct Connection
|
||||
{
|
||||
QPointer<QObject> sender;
|
||||
QPointer<QObject> receiver;
|
||||
const char* signal;
|
||||
const char* slot;
|
||||
};
|
||||
|
||||
void connect(const Connection& con);
|
||||
void disconnect(const Connection& con);
|
||||
|
||||
QPointer<QObject> m_currentObject;
|
||||
QList<Connection> m_connections;
|
||||
|
||||
Q_DISABLE_COPY(SignalMultiplexer)
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_SIGNALMULTIPLEXER_H
|
@ -51,7 +51,6 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
|
||||
setTabBar(tabBar);
|
||||
|
||||
connect(this, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
|
||||
connect(this, SIGNAL(currentChanged(int)), SLOT(emitEntrySelectionChanged()));
|
||||
connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType()));
|
||||
}
|
||||
|
||||
@ -177,18 +176,6 @@ void DatabaseTabWidget::importKeePass1Database()
|
||||
dbStruct.dbWidget->switchToImportKeepass1(fileName);
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::emitEntrySelectionChanged()
|
||||
{
|
||||
DatabaseWidget* dbWidget = currentDatabaseWidget();
|
||||
|
||||
bool isSingleEntrySelected = false;
|
||||
if (dbWidget) {
|
||||
isSingleEntrySelected = dbWidget->entryView()->isSingleEntrySelected();
|
||||
}
|
||||
|
||||
Q_EMIT entrySelectionChanged(isSingleEntrySelected);
|
||||
}
|
||||
|
||||
bool DatabaseTabWidget::closeDatabase(Database* db)
|
||||
{
|
||||
Q_ASSERT(db);
|
||||
@ -367,66 +354,6 @@ void DatabaseTabWidget::changeDatabaseSettings()
|
||||
currentDatabaseWidget()->switchToDatabaseSettings();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::createEntry()
|
||||
{
|
||||
currentDatabaseWidget()->createEntry();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::cloneEntry()
|
||||
{
|
||||
currentDatabaseWidget()->cloneEntry();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::editEntry()
|
||||
{
|
||||
currentDatabaseWidget()->switchToEntryEdit();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::deleteEntry()
|
||||
{
|
||||
currentDatabaseWidget()->deleteEntry();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::copyUsername()
|
||||
{
|
||||
currentDatabaseWidget()->copyUsername();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::copyPassword()
|
||||
{
|
||||
currentDatabaseWidget()->copyPassword();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::performAutoType()
|
||||
{
|
||||
currentDatabaseWidget()->performAutoType();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::openUrl()
|
||||
{
|
||||
currentDatabaseWidget()->openUrl();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::createGroup()
|
||||
{
|
||||
currentDatabaseWidget()->createGroup();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::editGroup()
|
||||
{
|
||||
currentDatabaseWidget()->switchToGroupEdit();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::deleteGroup()
|
||||
{
|
||||
currentDatabaseWidget()->deleteGroup();
|
||||
}
|
||||
|
||||
void DatabaseTabWidget::toggleSearch()
|
||||
{
|
||||
currentDatabaseWidget()->toggleSearch();
|
||||
}
|
||||
|
||||
bool DatabaseTabWidget::readOnly(int index)
|
||||
{
|
||||
if (index == -1) {
|
||||
@ -536,11 +463,7 @@ void DatabaseTabWidget::insertDatabase(Database* db, const DatabaseManagerStruct
|
||||
int index = databaseIndex(db);
|
||||
setCurrentIndex(index);
|
||||
connectDatabase(db);
|
||||
connect(dbStruct.dbWidget->entryView(), SIGNAL(entrySelectionChanged()),
|
||||
SLOT(emitEntrySelectionChanged()));
|
||||
connect(dbStruct.dbWidget, SIGNAL(closeRequest()), SLOT(closeDatabaseFromSender()));
|
||||
connect(dbStruct.dbWidget, SIGNAL(currentModeChanged(DatabaseWidget::Mode)),
|
||||
SIGNAL(currentWidgetModeChanged(DatabaseWidget::Mode)));
|
||||
connect(dbStruct.dbWidget, SIGNAL(databaseChanged(Database*)), SLOT(changeDatabase(Database*)));
|
||||
}
|
||||
|
||||
|
@ -67,30 +67,15 @@ public Q_SLOTS:
|
||||
bool closeAllDatabases();
|
||||
void changeMasterKey();
|
||||
void changeDatabaseSettings();
|
||||
void createEntry();
|
||||
void cloneEntry();
|
||||
void editEntry();
|
||||
void deleteEntry();
|
||||
void copyUsername();
|
||||
void copyPassword();
|
||||
void performAutoType();
|
||||
void openUrl();
|
||||
void createGroup();
|
||||
void editGroup();
|
||||
void deleteGroup();
|
||||
void toggleSearch();
|
||||
bool readOnly(int index = -1);
|
||||
void performGlobalAutoType();
|
||||
|
||||
Q_SIGNALS:
|
||||
void entrySelectionChanged(bool singleEntrySelected);
|
||||
void currentWidgetModeChanged(DatabaseWidget::Mode);
|
||||
void tabNameChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateTabName(Database* db);
|
||||
void updateTabNameFromSender();
|
||||
void emitEntrySelectionChanged();
|
||||
void modified();
|
||||
void toggleTabbar();
|
||||
void changeDatabase(Database* newDb);
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QSplitter>
|
||||
|
||||
@ -50,8 +49,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
||||
, m_newGroup(Q_NULLPTR)
|
||||
, m_newEntry(Q_NULLPTR)
|
||||
, m_newParent(Q_NULLPTR)
|
||||
, m_menuGroup(new QMenu(this))
|
||||
, m_menuEntry(new QMenu(this))
|
||||
{
|
||||
m_searchUi->setupUi(m_searchWidget);
|
||||
|
||||
@ -68,13 +65,15 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
||||
m_groupView = new GroupView(db, splitter);
|
||||
m_groupView->setObjectName("groupView");
|
||||
m_groupView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showGroupContextMenu(QPoint)));
|
||||
connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)),
|
||||
SLOT(emitGroupContextMenuRequested(QPoint)));
|
||||
|
||||
m_entryView = new EntryView(rightHandSideWidget);
|
||||
m_entryView->setObjectName("entryView");
|
||||
m_entryView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_entryView->setGroup(db->rootGroup());
|
||||
connect(m_entryView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showEntryContextMenu(QPoint)));
|
||||
connect(m_entryView, SIGNAL(customContextMenuRequested(QPoint)),
|
||||
SLOT(emitEntryContextMenuRequested(QPoint)));
|
||||
|
||||
QSizePolicy policy;
|
||||
policy = m_groupView->sizePolicy();
|
||||
@ -131,51 +130,11 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
||||
addWidget(m_databaseOpenWidget);
|
||||
addWidget(m_keepass1OpenWidget);
|
||||
|
||||
m_actionEntryNew = m_menuEntry->addAction(tr("Add new entry"), this,
|
||||
SLOT(createEntry()), Qt::CTRL + Qt::Key_N);
|
||||
m_actionEntryNew->setIcon(filePath()->icon("actions", "entry-new", false));
|
||||
m_actionEntryClone = m_menuEntry->addAction(tr("Clone entry"), this,
|
||||
SLOT(cloneEntry()), Qt::CTRL + Qt::Key_K);
|
||||
m_actionEntryClone->setIcon(filePath()->icon("actions", "entry-clone", false));
|
||||
m_actionEntryClone->setEnabled(false);
|
||||
m_actionEntryEditView = m_menuEntry->addAction(tr("View/Edit entry"), this,
|
||||
SLOT(switchToEntryEdit()), Qt::CTRL + Qt::Key_E);
|
||||
m_actionEntryEditView->setIcon(filePath()->icon("actions", "entry-edit", false));
|
||||
m_actionEntryEditView->setEnabled(false);
|
||||
m_actionEntryDelete = m_menuEntry->addAction(tr("Delete entry"), this,
|
||||
SLOT(deleteEntry()), Qt::CTRL + Qt::Key_D);
|
||||
m_actionEntryDelete->setIcon(filePath()->icon("actions", "entry-delete", false));
|
||||
m_actionEntryDelete->setEnabled(false);
|
||||
m_actionEntryCopyUsername = m_menuEntry->addAction(tr("Copy username to clipboard"), this,
|
||||
SLOT(copyUsername()), Qt::CTRL + Qt::Key_B);
|
||||
m_actionEntryCopyUsername->setEnabled(false);
|
||||
m_actionEntryCopyPassword = m_menuEntry->addAction(tr("Copy password to clipboard"), this,
|
||||
SLOT(copyPassword()), Qt::CTRL + Qt::Key_C);
|
||||
m_actionEntryCopyPassword->setEnabled(false);
|
||||
m_actionEntryAutoType = m_menuEntry->addAction(tr("Perform Auto-Type"), this,
|
||||
SLOT(performAutoType()));
|
||||
if (!QKeySequence::keyBindings(QKeySequence::Paste).isEmpty()) {
|
||||
m_actionEntryAutoType->setShortcuts(QKeySequence::Paste);
|
||||
}
|
||||
else {
|
||||
m_actionEntryAutoType->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V));
|
||||
}
|
||||
m_actionEntryAutoType->setEnabled(false);
|
||||
m_actionEntryOpenUrl = m_menuEntry->addAction(tr("Open URL"), this, SLOT(openUrl()), Qt::CTRL + Qt::Key_U);
|
||||
m_actionEntryOpenUrl->setEnabled(false);
|
||||
|
||||
m_actionGroupNew = m_menuGroup->addAction(tr("Add new group"), this, SLOT(createGroup()));
|
||||
m_actionGroupNew->setIcon(filePath()->icon("actions", "group-new", false));
|
||||
m_actionGroupEdit = m_menuGroup->addAction(tr("Edit group"), this, SLOT(switchToGroupEdit()));
|
||||
m_actionGroupEdit->setIcon(filePath()->icon("actions", "group-edit", false));
|
||||
m_actionGroupDelete = m_menuGroup->addAction(tr("Delete group"), this, SLOT(deleteGroup()));
|
||||
m_actionGroupDelete->setIcon(filePath()->icon("actions", "group-delete", false));
|
||||
m_actionGroupDelete->setEnabled(false);
|
||||
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*)));
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), SLOT(updateGroupActions(Group*)));
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
|
||||
connect(m_entryView, SIGNAL(entryActivated(Entry*)), SLOT(switchToEntryEdit(Entry*)));
|
||||
connect(m_entryView, SIGNAL(entrySelectionChanged()), SIGNAL(entrySelectionChanged()));
|
||||
connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool)));
|
||||
connect(m_editEntryWidget, SIGNAL(historyEntryActivated(Entry*)), SLOT(switchToHistoryView(Entry*)));
|
||||
connect(m_historyEditEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchBackToEntryEdit()));
|
||||
@ -191,7 +150,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
||||
connect(m_searchUi->searchRootRadioButton, SIGNAL(toggled(bool)), this, SLOT(startSearch()));
|
||||
connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(search()));
|
||||
connect(closeAction, SIGNAL(triggered()), this, SLOT(closeSearch()));
|
||||
connect(m_entryView, SIGNAL(entrySelectionChanged()), SLOT(updateEntryActions()));
|
||||
|
||||
setCurrentIndex(0);
|
||||
}
|
||||
@ -221,37 +179,6 @@ DatabaseWidget::Mode DatabaseWidget::currentMode()
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseWidget::actionEnabled(Action action)
|
||||
{
|
||||
switch (action) {
|
||||
case GroupNew:
|
||||
return m_actionGroupNew->isEnabled();
|
||||
case GroupEdit:
|
||||
return m_actionGroupEdit->isEnabled();
|
||||
case GroupDelete:
|
||||
return m_actionGroupDelete->isEnabled();
|
||||
case EntryNew:
|
||||
return m_actionEntryNew->isEnabled();
|
||||
case EntryClone:
|
||||
return m_actionEntryClone->isEnabled();
|
||||
case EntryEditView:
|
||||
return m_actionEntryEditView->isEnabled();
|
||||
case EntryDelete:
|
||||
return m_actionEntryDelete->isEnabled();
|
||||
case EntryCopyUsername:
|
||||
return m_actionEntryCopyUsername->isEnabled();
|
||||
case EntryCopyPassword:
|
||||
return m_actionEntryCopyPassword->isEnabled();
|
||||
case EntryAutoType:
|
||||
return m_actionEntryAutoType->isEnabled();
|
||||
case EntryOpenUrl:
|
||||
return m_actionEntryOpenUrl->isEnabled();
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWidget::emitCurrentModeChanged()
|
||||
{
|
||||
Q_EMIT currentModeChanged(currentMode());
|
||||
@ -680,6 +607,16 @@ void DatabaseWidget::startSearch()
|
||||
search();
|
||||
}
|
||||
|
||||
void DatabaseWidget::emitGroupContextMenuRequested(const QPoint& pos)
|
||||
{
|
||||
Q_EMIT groupContextMenuRequested(m_groupView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos)
|
||||
{
|
||||
Q_EMIT entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
bool DatabaseWidget::dbHasKey()
|
||||
{
|
||||
return m_db->hasKey();
|
||||
@ -692,6 +629,11 @@ bool DatabaseWidget::canDeleteCurrentGoup()
|
||||
return !isRootGroup && !isRecycleBin;
|
||||
}
|
||||
|
||||
bool DatabaseWidget::isInSearchMode()
|
||||
{
|
||||
return m_entryView->inEntryListMode();
|
||||
}
|
||||
|
||||
void DatabaseWidget::clearLastGroup(Group* group)
|
||||
{
|
||||
if (group) {
|
||||
@ -699,35 +641,3 @@ void DatabaseWidget::clearLastGroup(Group* group)
|
||||
m_searchWidget->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWidget::updateGroupActions(Group* group)
|
||||
{
|
||||
m_actionGroupNew->setEnabled(group);
|
||||
m_actionGroupEdit->setEnabled(group);
|
||||
m_actionGroupDelete->setEnabled(group && canDeleteCurrentGoup());
|
||||
}
|
||||
|
||||
void DatabaseWidget::updateEntryActions()
|
||||
{
|
||||
bool singleEntrySelected = m_entryView->isSingleEntrySelected();
|
||||
bool inSearch = m_entryView->inEntryListMode();
|
||||
|
||||
m_actionEntryNew->setEnabled(!inSearch);
|
||||
m_actionEntryClone->setEnabled(singleEntrySelected && !inSearch);
|
||||
m_actionEntryEditView->setEnabled(singleEntrySelected);
|
||||
m_actionEntryDelete->setEnabled(singleEntrySelected);
|
||||
m_actionEntryCopyUsername->setEnabled(singleEntrySelected);
|
||||
m_actionEntryCopyPassword->setEnabled(singleEntrySelected);
|
||||
m_actionEntryAutoType->setEnabled(singleEntrySelected);
|
||||
m_actionEntryOpenUrl->setEnabled(singleEntrySelected);
|
||||
}
|
||||
|
||||
void DatabaseWidget::showGroupContextMenu(const QPoint& pos)
|
||||
{
|
||||
m_menuGroup->popup(m_groupView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void DatabaseWidget::showEntryContextMenu(const QPoint& pos)
|
||||
{
|
||||
m_menuEntry->popup(m_entryView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
@ -52,20 +52,6 @@ public:
|
||||
ViewMode,
|
||||
EditMode
|
||||
};
|
||||
enum Action
|
||||
{
|
||||
GroupNew,
|
||||
GroupEdit,
|
||||
GroupDelete,
|
||||
EntryNew,
|
||||
EntryClone,
|
||||
EntryEditView,
|
||||
EntryDelete,
|
||||
EntryCopyUsername,
|
||||
EntryCopyPassword,
|
||||
EntryAutoType,
|
||||
EntryOpenUrl
|
||||
};
|
||||
|
||||
explicit DatabaseWidget(Database* db, QWidget* parent = Q_NULLPTR);
|
||||
~DatabaseWidget();
|
||||
@ -74,15 +60,19 @@ public:
|
||||
Database* database();
|
||||
bool dbHasKey();
|
||||
bool canDeleteCurrentGoup();
|
||||
bool isInSearchMode();
|
||||
int addWidget(QWidget* w);
|
||||
void setCurrentIndex(int index);
|
||||
DatabaseWidget::Mode currentMode();
|
||||
bool actionEnabled(Action action);
|
||||
|
||||
Q_SIGNALS:
|
||||
void closeRequest();
|
||||
void currentModeChanged(DatabaseWidget::Mode mode);
|
||||
void groupChanged();
|
||||
void entrySelectionChanged();
|
||||
void databaseChanged(Database* newDb);
|
||||
void groupContextMenuRequested(const QPoint& globalPos);
|
||||
void entryContextMenuRequested(const QPoint& globalPos);
|
||||
|
||||
public Q_SLOTS:
|
||||
void createEntry();
|
||||
@ -102,6 +92,8 @@ public Q_SLOTS:
|
||||
void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
|
||||
void switchToImportKeepass1(const QString& fileName);
|
||||
void toggleSearch();
|
||||
void emitGroupContextMenuRequested(const QPoint& pos);
|
||||
void emitEntryContextMenuRequested(const QPoint& pos);
|
||||
|
||||
private Q_SLOTS:
|
||||
void switchBackToEntryEdit();
|
||||
@ -119,10 +111,6 @@ private Q_SLOTS:
|
||||
void startSearchTimer();
|
||||
void showSearch();
|
||||
void closeSearch();
|
||||
void updateGroupActions(Group* group);
|
||||
void updateEntryActions();
|
||||
void showGroupContextMenu(const QPoint& pos);
|
||||
void showEntryContextMenu(const QPoint& pos);
|
||||
|
||||
private:
|
||||
Database* m_db;
|
||||
@ -143,21 +131,6 @@ private:
|
||||
Group* m_newParent;
|
||||
Group* m_lastGroup;
|
||||
QTimer* m_searchTimer;
|
||||
|
||||
QMenu* m_menuGroup;
|
||||
QAction* m_actionGroupNew;
|
||||
QAction* m_actionGroupEdit;
|
||||
QAction* m_actionGroupDelete;
|
||||
|
||||
QMenu* m_menuEntry;
|
||||
QAction* m_actionEntryNew;
|
||||
QAction* m_actionEntryClone;
|
||||
QAction* m_actionEntryEditView;
|
||||
QAction* m_actionEntryDelete;
|
||||
QAction* m_actionEntryCopyUsername;
|
||||
QAction* m_actionEntryCopyPassword;
|
||||
QAction* m_actionEntryAutoType;
|
||||
QAction* m_actionEntryOpenUrl;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_DATABASEWIDGET_H
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gui/AboutDialog.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
#include "gui/entry/EntryView.h"
|
||||
#include "gui/group/GroupView.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: m_ui(new Ui::MainWindow())
|
||||
@ -91,16 +92,25 @@ MainWindow::MainWindow()
|
||||
|
||||
m_ui->actionSearch->setIcon(filePath()->icon("actions", "system-search"));
|
||||
|
||||
connect(m_ui->tabWidget, SIGNAL(entrySelectionChanged(bool)),
|
||||
SLOT(setMenuActionState()));
|
||||
connect(m_ui->tabWidget, SIGNAL(currentWidgetModeChanged(DatabaseWidget::Mode)),
|
||||
SLOT(setMenuActionState(DatabaseWidget::Mode)));
|
||||
m_actionMultiplexer.connect(SIGNAL(currentModeChanged(DatabaseWidget::Mode)),
|
||||
this, SLOT(setMenuActionState(DatabaseWidget::Mode)));
|
||||
m_actionMultiplexer.connect(SIGNAL(groupChanged()),
|
||||
this, SLOT(setMenuActionState()));
|
||||
m_actionMultiplexer.connect(SIGNAL(entrySelectionChanged()),
|
||||
this, SLOT(setMenuActionState()));
|
||||
m_actionMultiplexer.connect(SIGNAL(groupContextMenuRequested(QPoint)),
|
||||
this, SLOT(showGroupContextMenu(QPoint)));
|
||||
m_actionMultiplexer.connect(SIGNAL(entryContextMenuRequested(QPoint)),
|
||||
this, SLOT(showEntryContextMenu(QPoint)));
|
||||
|
||||
connect(m_ui->tabWidget, SIGNAL(tabNameChanged()),
|
||||
SLOT(updateWindowTitle()));
|
||||
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)),
|
||||
SLOT(updateWindowTitle()));
|
||||
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)),
|
||||
SLOT(databaseTabChanged(int)));
|
||||
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)),
|
||||
SLOT(setMenuActionState()));
|
||||
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState()));
|
||||
connect(m_ui->settingsWidget, SIGNAL(editFinished(bool)), SLOT(switchToDatabases()));
|
||||
|
||||
@ -122,36 +132,36 @@ MainWindow::MainWindow()
|
||||
SLOT(importKeePass1Database()));
|
||||
connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(close()));
|
||||
|
||||
connect(m_ui->actionEntryNew, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryNew, SIGNAL(triggered()),
|
||||
SLOT(createEntry()));
|
||||
connect(m_ui->actionEntryClone, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryClone, SIGNAL(triggered()),
|
||||
SLOT(cloneEntry()));
|
||||
connect(m_ui->actionEntryEdit, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
SLOT(editEntry()));
|
||||
connect(m_ui->actionEntryDelete, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryEdit, SIGNAL(triggered()),
|
||||
SLOT(switchToEntryEdit()));
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()),
|
||||
SLOT(deleteEntry()));
|
||||
connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()),
|
||||
SLOT(copyUsername()));
|
||||
connect(m_ui->actionEntryCopyPassword, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryCopyPassword, SIGNAL(triggered()),
|
||||
SLOT(copyPassword()));
|
||||
connect(m_ui->actionEntryAutoType, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryAutoType, SIGNAL(triggered()),
|
||||
SLOT(performAutoType()));
|
||||
connect(m_ui->actionEntryOpenUrl, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryOpenUrl, SIGNAL(triggered()),
|
||||
SLOT(openUrl()));
|
||||
|
||||
connect(m_ui->actionGroupNew, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionGroupNew, SIGNAL(triggered()),
|
||||
SLOT(createGroup()));
|
||||
connect(m_ui->actionGroupEdit, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
SLOT(editGroup()));
|
||||
connect(m_ui->actionGroupDelete, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
m_actionMultiplexer.connect(m_ui->actionGroupEdit, SIGNAL(triggered()),
|
||||
SLOT(switchToGroupEdit()));
|
||||
m_actionMultiplexer.connect(m_ui->actionGroupDelete, SIGNAL(triggered()),
|
||||
SLOT(deleteGroup()));
|
||||
|
||||
connect(m_ui->actionSettings, SIGNAL(triggered()), SLOT(switchToSettings()));
|
||||
|
||||
connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog()));
|
||||
|
||||
connect(m_ui->actionSearch, SIGNAL(triggered()), m_ui->tabWidget,
|
||||
SLOT(toggleSearch()));
|
||||
m_actionMultiplexer.connect(m_ui->actionSearch, SIGNAL(triggered()),
|
||||
SLOT(toggleSearch()));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -202,20 +212,24 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
||||
|
||||
switch (mode) {
|
||||
case DatabaseWidget::ViewMode: {
|
||||
m_ui->actionEntryNew->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryNew));
|
||||
m_ui->actionEntryClone->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryClone));
|
||||
m_ui->actionEntryEdit->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryEditView));
|
||||
m_ui->actionEntryDelete->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryDelete));
|
||||
m_ui->actionEntryCopyUsername->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryCopyUsername));
|
||||
m_ui->actionEntryCopyPassword->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryCopyPassword));
|
||||
m_ui->actionEntryAutoType->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryAutoType));
|
||||
m_ui->actionEntryOpenUrl->setEnabled(dbWidget->actionEnabled(DatabaseWidget::EntryOpenUrl));
|
||||
m_ui->actionGroupNew->setEnabled(dbWidget->actionEnabled(DatabaseWidget::GroupNew));
|
||||
m_ui->actionGroupEdit->setEnabled(dbWidget->actionEnabled(DatabaseWidget::GroupEdit));
|
||||
m_ui->actionGroupDelete->setEnabled(dbWidget->actionEnabled(DatabaseWidget::GroupDelete));
|
||||
bool inSearch = dbWidget->isInSearchMode();
|
||||
bool singleEntrySelected = dbWidget->entryView()->isSingleEntrySelected();
|
||||
bool groupSelected = dbWidget->groupView()->currentGroup();
|
||||
|
||||
m_ui->actionEntryNew->setEnabled(!inSearch);
|
||||
m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inSearch);
|
||||
m_ui->actionEntryEdit->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryDelete->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryCopyUsername->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryCopyPassword->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected);
|
||||
m_ui->actionGroupNew->setEnabled(groupSelected);
|
||||
m_ui->actionGroupEdit->setEnabled(groupSelected);
|
||||
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGoup());
|
||||
m_ui->actionSearch->setEnabled(true);
|
||||
// TODO: get checked state from db widget
|
||||
m_ui->actionSearch->setChecked(dbWidget->entryView()->inEntryListMode());
|
||||
m_ui->actionSearch->setChecked(inSearch);
|
||||
m_ui->actionChangeMasterKey->setEnabled(true);
|
||||
m_ui->actionChangeDatabaseSettings->setEnabled(true);
|
||||
m_ui->actionDatabaseSave->setEnabled(true);
|
||||
@ -223,17 +237,14 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
||||
break;
|
||||
}
|
||||
case DatabaseWidget::EditMode:
|
||||
m_ui->actionEntryNew->setEnabled(false);
|
||||
m_ui->actionEntryClone->setEnabled(false);
|
||||
m_ui->actionEntryEdit->setEnabled(false);
|
||||
m_ui->actionEntryDelete->setEnabled(false);
|
||||
m_ui->actionEntryCopyUsername->setEnabled(false);
|
||||
m_ui->actionEntryCopyPassword->setEnabled(false);
|
||||
m_ui->actionEntryAutoType->setEnabled(false);
|
||||
m_ui->actionEntryOpenUrl->setEnabled(false);
|
||||
m_ui->actionGroupNew->setEnabled(false);
|
||||
m_ui->actionGroupEdit->setEnabled(false);
|
||||
m_ui->actionGroupDelete->setEnabled(false);
|
||||
Q_FOREACH (QAction* action, m_ui->menuEntries->actions()) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
|
||||
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
|
||||
m_ui->actionSearch->setEnabled(false);
|
||||
m_ui->actionSearch->setChecked(false);
|
||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||
@ -247,17 +258,14 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
||||
m_ui->actionDatabaseClose->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
m_ui->actionEntryNew->setEnabled(false);
|
||||
m_ui->actionEntryClone->setEnabled(false);
|
||||
m_ui->actionEntryEdit->setEnabled(false);
|
||||
m_ui->actionEntryDelete->setEnabled(false);
|
||||
m_ui->actionEntryCopyUsername->setEnabled(false);
|
||||
m_ui->actionEntryCopyPassword->setEnabled(false);
|
||||
m_ui->actionEntryAutoType->setEnabled(false);
|
||||
m_ui->actionEntryOpenUrl->setEnabled(false);
|
||||
m_ui->actionGroupNew->setEnabled(false);
|
||||
m_ui->actionGroupEdit->setEnabled(false);
|
||||
m_ui->actionGroupDelete->setEnabled(false);
|
||||
Q_FOREACH (QAction* action, m_ui->menuEntries->actions()) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
|
||||
Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
|
||||
m_ui->actionSearch->setEnabled(false);
|
||||
m_ui->actionSearch->setChecked(false);
|
||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||
@ -320,6 +328,8 @@ void MainWindow::databaseTabChanged(int tabIndex)
|
||||
else if (tabIndex == -1 && m_ui->stackedWidget->currentIndex() == 0) {
|
||||
m_ui->stackedWidget->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
m_actionMultiplexer.setCurrentObject(m_ui->tabWidget->currentDatabaseWidget());
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
@ -332,6 +342,16 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::showEntryContextMenu(const QPoint& globalPos)
|
||||
{
|
||||
m_ui->menuEntries->popup(globalPos);
|
||||
}
|
||||
|
||||
void MainWindow::showGroupContextMenu(const QPoint& globalPos)
|
||||
{
|
||||
m_ui->menuGroups->popup(globalPos);
|
||||
}
|
||||
|
||||
void MainWindow::setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback)
|
||||
{
|
||||
if (!QKeySequence::keyBindings(standard).isEmpty()) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QMainWindow>
|
||||
|
||||
#include "core/SignalMultiplexer.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
@ -52,6 +53,8 @@ private Q_SLOTS:
|
||||
void openRecentDatabase(QAction* action);
|
||||
void clearLastDatabases();
|
||||
void updateLastDatabasesMenu();
|
||||
void showEntryContextMenu(const QPoint& globalPos);
|
||||
void showGroupContextMenu(const QPoint& globalPos);
|
||||
|
||||
private:
|
||||
static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);
|
||||
@ -59,6 +62,7 @@ private:
|
||||
static const QString BaseWindowTitle;
|
||||
|
||||
const QScopedPointer<Ui::MainWindow> m_ui;
|
||||
SignalMultiplexer m_actionMultiplexer;
|
||||
QAction* m_clearHistoryAction;
|
||||
QActionGroup* m_lastDatabasesActions;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user