Add config options, remove deprecations, optimize

master
alex1701c 6 years ago
parent c0c88e97d1
commit 7194271cec
  1. 2
      CMakeLists.txt
  2. 3
      README.md
  3. 89
      config.cpp
  4. 1
      config.h
  5. 49
      config.ui
  6. 2
      install.sh
  7. 61
      pass.cpp
  8. 6
      pass.h

@ -44,6 +44,6 @@ target_link_libraries(krunner_pass KF5::Runner Qt5::Widgets
add_dependencies(krunner_pass kcm_krunner_pass)
install(TARGETS krunner_pass kcm_krunner_pass DESTINATION ${PLUGIN_INSTALL_DIR})
install(TARGETS krunner_pass kcm_krunner_pass DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
install(FILES plasma-runner-pass.desktop plasma-runner-pass_config.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(FILES krunner_pass.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})

@ -34,7 +34,8 @@ apt-get install build-essential cmake extra-cmake-modules gettext \
libkf5service-dev \
libkf5runner-dev \
libkf5textwidgets-dev \
libkf5notifications-dev
libkf5notifications-dev \
libkf5kcmutils-dev
mkdir -p build
cd build

@ -22,13 +22,13 @@
#include <QToolButton>
#include <QtCore/QDir>
#include "kcmutils_version.h"
#include "config.h"
K_PLUGIN_FACTORY(PassConfigFactory, registerPlugin<PassConfig>("kcm_krunner_pass");)
PassConfigForm::PassConfigForm(QWidget *parent) : QWidget(parent)
PassConfigForm::PassConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
this->listSavedActions->setDragEnabled(true);
@ -49,16 +49,17 @@ PassConfigForm::PassConfigForm(QWidget *parent) : QWidget(parent)
});
// Disable add button if the necessary field are not filled out
connect(this->lineIcon, SIGNAL(textChanged(QString)), this, SLOT(validateAddButton()));
connect(this->lineName, SIGNAL(textChanged(QString)), this, SLOT(validateAddButton()));
connect(this->lineRegEx, SIGNAL(textChanged(QString)), this, SLOT(validateAddButton()));
connect(this->lineIcon, &QLineEdit::textChanged, this, &PassConfigForm::validateAddButton);
connect(this->lineName, &QLineEdit::textChanged, this, &PassConfigForm::validateAddButton);
connect(this->lineRegEx, &QLineEdit::textChanged, this, &PassConfigForm::validateAddButton);
validateAddButton();
}
void PassConfigForm::addPassAction(const QString &name, const QString &icon, const QString &regex, bool isNew /* = true */)
void
PassConfigForm::addPassAction(const QString &name, const QString &icon, const QString &regex, bool isNew /* = true */)
{
// Checks
for (const auto& act: this->passActions())
for (const auto &act: this->passActions())
if (act.name == name)
return;
@ -74,8 +75,8 @@ void PassConfigForm::addPassAction(const QString &name, const QString &icon, con
listWidget->setLayout(layoutAction);
// Item
auto *item = new QListWidgetItem(name + (isNew ? "*":""), this->listSavedActions);
item->setData(Qt::UserRole, QVariant::fromValue(PassAction {name, icon, regex}));
auto *item = new QListWidgetItem(name + (isNew ? "*" : ""), this->listSavedActions);
item->setData(Qt::UserRole, QVariant::fromValue(PassAction{name, icon, regex}));
this->listSavedActions->setItemWidget(item, listWidget);
this->clearInputs();
@ -95,9 +96,8 @@ void PassConfigForm::addPassAction(const QString &name, const QString &icon, con
QVector<PassAction> PassConfigForm::passActions()
{
QVector<PassAction> passActions;
const int listSavedActionsCount = this->listSavedActions->count();
for(int i = 0; i < listSavedActionsCount; ++i) {
QListWidgetItem* item = this->listSavedActions->item(i);
for (int i = 0; i < listSavedActions->count(); ++i) {
QListWidgetItem *item = this->listSavedActions->item(i);
passActions << item->data(Qt::UserRole).value<PassAction>();
}
return passActions;
@ -105,9 +105,8 @@ QVector<PassAction> PassConfigForm::passActions()
void PassConfigForm::clearPassActions()
{
const int listSavedActionsCount = this->listSavedActions->count();
for(int i = 0; i < listSavedActionsCount; ++i) {
QListWidgetItem* item = this->listSavedActions->item(i);
for (int i = 0; i < listSavedActions->count(); ++i) {
QListWidgetItem *item = this->listSavedActions->item(i);
delete this->listSavedActions->itemWidget(item);
}
@ -121,25 +120,31 @@ void PassConfigForm::clearInputs()
this->lineRegEx->clear();
}
void PassConfigForm::validateAddButton() {
void PassConfigForm::validateAddButton()
{
this->buttonAddAction->setDisabled(this->lineIcon->text().isEmpty() ||
this->lineName->text().isEmpty() ||
this->lineRegEx->text().isEmpty());
this->lineName->text().isEmpty() ||
this->lineRegEx->text().isEmpty());
}
PassConfig::PassConfig(QWidget *parent, const QVariantList &args) :
PassConfig::PassConfig(QWidget *parent, const QVariantList &args)
:
KCModule(parent, args)
{
this->ui = new PassConfigForm(this);
QGridLayout* layout = new QGridLayout(this);
QGridLayout *layout = new QGridLayout(this);
layout->addWidget(ui, 0, 0);
connect(this->ui,SIGNAL(passActionAdded()),this,SLOT(changed()));
connect(this->ui,SIGNAL(passActionRemoved()),this,SLOT(changed()));
connect(this->ui->checkAdditionalActions,SIGNAL(stateChanged(int)),this,SLOT(changed()));
connect(this->ui->checkShowFileContentAction,SIGNAL(stateChanged(int)),this,SLOT(changed()));
connect(this->ui->listSavedActions,SIGNAL(itemSelectionChanged()), this, SLOT(changed()));
#if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 64, 0)
const auto changedSlotPointer = &PassConfig::markAsChanged;
#else
const auto changedSlotPointer = static_cast<void (PassConfig::*)()>(&PassConfig::changed);
#endif
connect(this->ui, &PassConfigForm::passActionAdded, this, changedSlotPointer);
connect(this->ui, &PassConfigForm::passActionRemoved, this, changedSlotPointer);
connect(this->ui->checkShowOnlyPrefixed, &QCheckBox::stateChanged, this, changedSlotPointer);
connect(this->ui->checkAdditionalActions, &QCheckBox::stateChanged, this, changedSlotPointer);
connect(this->ui->checkShowFileContentAction, &QCheckBox::stateChanged, this, changedSlotPointer);
connect(this->ui->listSavedActions, &QListWidget::itemSelectionChanged, this, changedSlotPointer);
}
void PassConfig::load()
@ -147,13 +152,13 @@ void PassConfig::load()
KCModule::load();
KSharedConfig::Ptr cfg = KSharedConfig::openConfig(QStringLiteral("krunnerrc"));
KConfigGroup passCfg = cfg->group("Runners");
passCfg = KConfigGroup(&passCfg, "Pass");
KConfigGroup passCfg = cfg->group("Runners").group("Pass");
bool showOnlyPrefixed = passCfg.readEntry(Config::showOnlyPrefixed, false);
bool showActions = passCfg.readEntry(Config::showActions, false);
bool showFileContentAction = passCfg.readEntry(Config::showFileContentAction, false);
this->ui->checkShowOnlyPrefixed->setChecked(showOnlyPrefixed);
this->ui->checkAdditionalActions->setChecked(showActions);
this->ui->checkShowFileContentAction->setChecked(showFileContentAction);
@ -161,14 +166,11 @@ void PassConfig::load()
this->ui->clearPassActions();
const auto actionGroup = passCfg.group(Config::Group::Actions);
for (const auto& name: actionGroup.groupList()) {
for (const auto &name: actionGroup.groupList()) {
auto group = actionGroup.group(name);
auto passAction = PassAction::fromConfig(group);
this->ui->addPassAction(passAction.name, passAction.icon, passAction.regex, false);
}
emit changed(false);
}
void PassConfig::save()
@ -176,13 +178,13 @@ void PassConfig::save()
KCModule::save();
KSharedConfig::Ptr cfg = KSharedConfig::openConfig(QStringLiteral("krunnerrc"));
KConfigGroup passCfg = cfg->group("Runners");
passCfg = KConfigGroup(&passCfg, "Pass");
KConfigGroup passCfg = cfg->group("Runners").group("Pass");
auto showOnlyPrefixed = this->ui->checkShowOnlyPrefixed->isChecked();
auto showActions = this->ui->checkAdditionalActions->isChecked();
auto showFileContentAction = this->ui->checkShowFileContentAction->isChecked();
auto showFileContentAction = this->ui->checkShowFileContentAction->isChecked();
passCfg.writeEntry(Config::showOnlyPrefixed, showOnlyPrefixed);
passCfg.writeEntry(Config::showActions, showActions);
passCfg.writeEntry(Config::showFileContentAction, showFileContentAction);
@ -190,25 +192,28 @@ void PassConfig::save()
if (showActions) {
int i = 0;
for (PassAction& act: this->ui->passActions()) {
for (PassAction &act: this->ui->passActions()) {
auto group = passCfg.group(Config::Group::Actions).group(QString::number(i++));
act.writeToConfig(group);
}
}
emit changed(false);
}
void PassConfig::defaults()
{
KCModule::defaults();
ui->checkShowOnlyPrefixed->setChecked(false);
ui->checkAdditionalActions->setChecked(false);
ui->checkShowFileContentAction->setChecked(false);
ui->clearPassActions();
ui->clearInputs();
#if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 64, 0)
emit markAsChanged();
#else
emit changed(true);
#endif
}

@ -25,6 +25,7 @@
struct Config {
constexpr static const char *showOnlyPrefixed = "showOnlyPrefixed";
constexpr static const char *showActions = "showAdditionalActions";
constexpr static const char *showFileContentAction = "showFullFileContentAction";
struct Group {

@ -6,32 +6,37 @@
<rect>
<x>0</x>
<y>0</y>
<width>314</width>
<height>420</height>
<width>356</width>
<height>421</height>
</rect>
</property>
<property name="windowTitle">
<string>Pass Config</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="checkAdditionalActions">
<property name="text">
<string>Show additional actions</string>
<item row="4" column="0">
<widget class="QGroupBox" name="boxSavedActions">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Saved Actions</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QListWidget" name="listSavedActions"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkShowFileContentAction">
<property name="enabled">
<bool>false</bool>
</property>
<widget class="QCheckBox" name="checkAdditionalActions">
<property name="text">
<string>Show an action for displaying full file content</string>
<string>Show additional actions</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QGroupBox" name="boxNewAction">
<property name="enabled">
<bool>false</bool>
@ -93,19 +98,21 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="boxSavedActions">
<item row="2" column="0">
<widget class="QCheckBox" name="checkShowFileContentAction">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Saved Actions</string>
<property name="text">
<string>Show an action for displaying full file content</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkShowOnlyPrefixed">
<property name="text">
<string>Show only options when query starts with &quot;pass&quot;</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QListWidget" name="listSavedActions"/>
</item>
</layout>
</widget>
</item>
</layout>

@ -5,7 +5,7 @@ set -e
mkdir -p build
cd build
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_INSTALL_PREFIX=`kf5-config --prefix` -DQT_PLUGIN_INSTALL_DIR=`kf5-config --qt-plugins` -DCMAKE_BUILD_TYPE=Release
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_INSTALL_PREFIX=`kf5-config --prefix` -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
sudo make install

@ -17,7 +17,7 @@
*****************************************************************************/
#include <KSharedConfig>
#include <KLocalizedString>
#include <knotification.h>
#include <KNotification>
#include <QAction>
#include <QDirIterator>
@ -60,20 +60,24 @@ void Pass::reloadConfiguration()
KConfigGroup cfg = config();
this->showActions = cfg.readEntry(Config::showActions, false);
this->showOnlyPrefixed = cfg.readEntry(Config::showOnlyPrefixed, false);
if (showActions) {
const auto configActions = cfg.group(Config::Group::Actions);
// Create actions for every additional field
for (const auto& name: configActions.groupList() ) {
for (const auto &name: configActions.groupList()) {
auto group = configActions.group(name);
auto passAction = PassAction::fromConfig(group);
auto icon = QIcon::fromTheme(passAction.icon, QIcon::fromTheme("object-unlocked"));
QAction *act = addAction(passAction.name, icon , passAction.name);
QAction *act = addAction(passAction.name, icon, passAction.name);
act->setData(passAction.regex);
this->orderedActions << act;
}
} else {
this->orderedActions.clear();
}
if (cfg.readEntry(Config::showFileContentAction, false)) {
@ -113,10 +117,11 @@ void Pass::init()
initPasswords();
connect(&watcher, SIGNAL(directoryChanged(QString)), this, SLOT(reinitPasswords(QString)));
connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &Pass::reinitPasswords);
}
void Pass::initPasswords() {
void Pass::initPasswords()
{
passwords.clear();
watcher.addPath(this->baseDir.absolutePath());
@ -124,7 +129,7 @@ void Pass::initPasswords() {
while (it.hasNext()) {
it.next();
const auto fileInfo = it.fileInfo();
if (fileInfo.isFile() && fileInfo.suffix() == "gpg") {
if (fileInfo.isFile() && fileInfo.suffix() == QLatin1String("gpg")) {
QString password = this->baseDir.relativeFilePath(fileInfo.absoluteFilePath());
// Remove suffix ".gpg"
password.chop(4);
@ -135,7 +140,8 @@ void Pass::initPasswords() {
}
}
void Pass::reinitPasswords(const QString &path) {
void Pass::reinitPasswords(const QString &path)
{
Q_UNUSED(path);
lock.lockForWrite();
@ -145,18 +151,27 @@ void Pass::reinitPasswords(const QString &path) {
void Pass::match(Plasma::RunnerContext &context)
{
if (!context.isValid()) return;
if (!context.isValid()) {
return;
}
const auto input = context.query();
auto input = context.query();
if (showOnlyPrefixed) {
if (input.startsWith(queryPrefix)) {
input = input.remove(queryPrefix).simplified();
} else {
return;
}
}
QList<Plasma::QueryMatch> matches;
lock.lockForRead();
for (const auto& password: passwords) {
if (password.contains(input,Qt::CaseInsensitive)) {
for (const auto &password: qAsConst(passwords)) {
if (password.contains(input, Qt::CaseInsensitive)) {
Plasma::QueryMatch match(this);
match.setType(input.length() == password.length() ?
Plasma::QueryMatch::ExactMatch : Plasma::QueryMatch::CompletionMatch);
Plasma::QueryMatch::ExactMatch : Plasma::QueryMatch::CompletionMatch);
match.setIcon(QIcon::fromTheme("object-locked"));
match.setText(password);
matches.append(match);
@ -172,8 +187,8 @@ void Pass::clip(const QString &msg)
QClipboard *cb = QApplication::clipboard();
cb->setText(msg);
QTimer::singleShot(timeout * 1000, cb, [cb]() {
cb->clear();
});
cb->setText(QString());
});
}
void Pass::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
@ -185,10 +200,9 @@ void Pass::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &m
auto *pass = new QProcess();
QStringList args;
if (isOtp) {
args << "otp" << "show" << match.text();
} else {
args << "show" << match.text();
args << "otp";
}
args << "show" << match.text();
pass->start("pass", args);
connect(pass, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
@ -239,19 +253,16 @@ QList<QAction *> Pass::actionsForMatch(const Plasma::QueryMatch &match)
{
Q_UNUSED(match)
if (showActions)
return this->orderedActions;
return QList<QAction *>();
return this->orderedActions;
}
void Pass::showNotification(const QString &text, const QString &actionName /* = "" */)
void Pass::showNotification(const QString &text, const QString &actionName)
{
const QString msgPrefix = actionName.isEmpty() ? "":actionName + i18n(" of ");
const QString msgPrefix = actionName.isEmpty() ? "" : actionName + i18n(" of ");
const QString msg = i18n("Password %1 copied to clipboard for %2 seconds", text, timeout);
KNotification::event("password-unlocked", "Pass", msgPrefix + msg,
"object-unlocked", nullptr, KNotification::CloseOnTimeout,
"krunner_pass");
"object-unlocked", nullptr, KNotification::CloseOnTimeout,
"krunner_pass");
}
K_EXPORT_PLASMA_RUNNER(pass, Pass)

@ -45,7 +45,7 @@ public slots:
protected:
void init() override;
void initPasswords();
void showNotification(const QString &, const QString & = "");
void showNotification(const QString &, const QString & = QString());
private:
QDir baseDir;
@ -57,7 +57,9 @@ private:
bool showActions;
QList<QAction *> orderedActions;
bool showOnlyPrefixed;
QLatin1String queryPrefix = QLatin1String("pass");
};
#endif

Loading…
Cancel
Save