Refactor various aspects of the code
* Prefer using auto * Reduce nesting in certain places * Simplify code in main function
This commit is contained in:
parent
0f4c30c14f
commit
b2d85c7d53
92
cli/cli.cpp
92
cli/cli.cpp
|
@ -5,6 +5,7 @@
|
||||||
#include <passwordfile/io/field.h>
|
#include <passwordfile/io/field.h>
|
||||||
#include <passwordfile/io/parsingexception.h>
|
#include <passwordfile/io/parsingexception.h>
|
||||||
#include <passwordfile/io/passwordfile.h>
|
#include <passwordfile/io/passwordfile.h>
|
||||||
|
#include <passwordfile/util/openssl.h>
|
||||||
|
|
||||||
#include <c++utilities/application/commandlineutils.h>
|
#include <c++utilities/application/commandlineutils.h>
|
||||||
#include <c++utilities/conversion/stringconversion.h>
|
#include <c++utilities/conversion/stringconversion.h>
|
||||||
|
@ -15,7 +16,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
@ -89,32 +92,39 @@ InteractiveCli::InteractiveCli()
|
||||||
, m_modified(false)
|
, m_modified(false)
|
||||||
, m_quit(false)
|
, m_quit(false)
|
||||||
{
|
{
|
||||||
|
Util::OpenSsl::init();
|
||||||
CMD_UTILS_START_CONSOLE;
|
CMD_UTILS_START_CONSOLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::run(const string &file)
|
InteractiveCli::~InteractiveCli()
|
||||||
|
{
|
||||||
|
Util::OpenSsl::clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
int InteractiveCli::run(string_view file)
|
||||||
{
|
{
|
||||||
if (!file.empty()) {
|
if (!file.empty()) {
|
||||||
openFile(file, PasswordFileOpenFlags::Default);
|
openFile(file, PasswordFileOpenFlags::Default);
|
||||||
}
|
}
|
||||||
string input;
|
auto input = std::string();
|
||||||
while (!m_quit) {
|
while (!m_quit) {
|
||||||
getline(m_i, input);
|
std::getline(m_i, input);
|
||||||
if (!input.empty()) {
|
if (!input.empty()) {
|
||||||
processCommand(input);
|
processCommand(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::processCommand(const string &cmd)
|
void InteractiveCli::processCommand(const std::string &cmd)
|
||||||
{
|
{
|
||||||
#define CMD(value) !paramMissing &&cmd == value
|
#define CMD(value) !paramMissing &&cmd == value
|
||||||
#define CMD2(value1, value2) !paramMissing && (cmd == value1 || cmd == value2)
|
#define CMD2(value1, value2) !paramMissing && (cmd == value1 || cmd == value2)
|
||||||
#define CMD_P(value) !paramMissing &&checkCommand(cmd, value, param, paramMissing)
|
#define CMD_P(value) !paramMissing &&checkCommand(cmd, value, param, paramMissing)
|
||||||
#define CMD2_P(value1, value2) !paramMissing && (checkCommand(cmd, value1, param, paramMissing) || checkCommand(cmd, value2, param, paramMissing))
|
#define CMD2_P(value1, value2) !paramMissing && (checkCommand(cmd, value1, param, paramMissing) || checkCommand(cmd, value2, param, paramMissing))
|
||||||
|
|
||||||
string param;
|
auto param = std::string();
|
||||||
bool paramMissing = false;
|
auto paramMissing = false;
|
||||||
if (CMD2("quit", "q")) {
|
if (CMD2("quit", "q")) {
|
||||||
quit();
|
quit();
|
||||||
} else if (CMD("q!")) {
|
} else if (CMD("q!")) {
|
||||||
|
@ -175,9 +185,9 @@ void InteractiveCli::processCommand(const string &cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry *InteractiveCli::resolvePath(const string &path)
|
Entry *InteractiveCli::resolvePath(const std::string &path)
|
||||||
{
|
{
|
||||||
auto parts = splitString<vector<string>>(path, "/", EmptyPartsTreat::Merge);
|
auto parts = splitString<std::vector<std::string>>(path, "/", EmptyPartsTreat::Merge);
|
||||||
bool fromRoot = path.at(0) == '/';
|
bool fromRoot = path.at(0) == '/';
|
||||||
if (fromRoot && parts.empty()) {
|
if (fromRoot && parts.empty()) {
|
||||||
return m_file.rootEntry();
|
return m_file.rootEntry();
|
||||||
|
@ -213,7 +223,7 @@ Entry *InteractiveCli::resolvePath(const string &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InteractiveCli::checkCommand(const string &str, const char *phrase, std::string ¶m, bool ¶mMissing)
|
bool InteractiveCli::checkCommand(const std::string &str, const char *phrase, std::string ¶m, bool ¶mMissing)
|
||||||
{
|
{
|
||||||
for (auto i = str.cbegin(), end = str.cend(); i != end; ++i, ++phrase) {
|
for (auto i = str.cbegin(), end = str.cend(); i != end; ++i, ++phrase) {
|
||||||
if (*phrase == 0) {
|
if (*phrase == 0) {
|
||||||
|
@ -234,13 +244,13 @@ bool InteractiveCli::checkCommand(const string &str, const char *phrase, std::st
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::openFile(const string &file, PasswordFileOpenFlags openFlags)
|
void InteractiveCli::openFile(std::string_view file, PasswordFileOpenFlags openFlags)
|
||||||
{
|
{
|
||||||
if (m_file.isOpen()) {
|
if (m_file.isOpen()) {
|
||||||
m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl;
|
m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_file.setPath(file);
|
m_file.setPath(std::string(file));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
|
@ -322,7 +332,7 @@ void InteractiveCli::saveFile()
|
||||||
m_modified = false;
|
m_modified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::createFile(const string &file)
|
void InteractiveCli::createFile(const std::string &file)
|
||||||
{
|
{
|
||||||
if (m_file.isOpen()) {
|
if (m_file.isOpen()) {
|
||||||
m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl;
|
m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl;
|
||||||
|
@ -392,7 +402,7 @@ void InteractiveCli::pwd()
|
||||||
m_o << joinStrings(path, "/") << endl;
|
m_o << joinStrings(path, "/") << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::cd(const string &path)
|
void InteractiveCli::cd(const std::string &path)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not change directory; no file open" << endl;
|
m_o << "can not change directory; no file open" << endl;
|
||||||
|
@ -450,7 +460,7 @@ void InteractiveCli::tree()
|
||||||
printEntries(m_currentEntry, 0);
|
printEntries(m_currentEntry, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::makeEntry(EntryType entryType, const string &label)
|
void InteractiveCli::makeEntry(EntryType entryType, const std::string &label)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not make entry; no file open" << endl;
|
m_o << "can not make entry; no file open" << endl;
|
||||||
|
@ -473,7 +483,7 @@ void InteractiveCli::makeEntry(EntryType entryType, const string &label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::removeEntry(const string &path)
|
void InteractiveCli::removeEntry(const std::string &path)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not remove entry; no file open" << endl;
|
m_o << "can not remove entry; no file open" << endl;
|
||||||
|
@ -493,16 +503,16 @@ void InteractiveCli::removeEntry(const string &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::renameEntry(const string &path)
|
void InteractiveCli::renameEntry(const std::string &path)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not rename entry; no file open" << endl;
|
m_o << "can not rename entry; no file open" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Entry *entry = resolvePath(path)) {
|
if (Entry *entry = resolvePath(path)) {
|
||||||
string label;
|
auto label = std::string();
|
||||||
m_o << "enter new name: " << endl;
|
m_o << "enter new name: " << endl;
|
||||||
getline(m_i, label);
|
std::getline(m_i, label);
|
||||||
if (label.empty()) {
|
if (label.empty()) {
|
||||||
m_o << "can not rename; new name is empty" << endl;
|
m_o << "can not rename; new name is empty" << endl;
|
||||||
} else {
|
} else {
|
||||||
|
@ -513,16 +523,16 @@ void InteractiveCli::renameEntry(const string &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::moveEntry(const string &path)
|
void InteractiveCli::moveEntry(const std::string &path)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not rename entry; no file open" << endl;
|
m_o << "can not rename entry; no file open" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Entry *entry = resolvePath(path)) {
|
if (Entry *entry = resolvePath(path)) {
|
||||||
string newParentPath;
|
auto newParentPath = std::string();
|
||||||
m_o << "enter path of new parent: " << endl;
|
m_o << "enter path of new parent: " << endl;
|
||||||
getline(m_i, newParentPath);
|
std::getline(m_i, newParentPath);
|
||||||
if (newParentPath.empty()) {
|
if (newParentPath.empty()) {
|
||||||
m_o << "can not move; path of new parent is empty" << endl;
|
m_o << "can not move; path of new parent is empty" << endl;
|
||||||
} else {
|
} else {
|
||||||
|
@ -547,7 +557,7 @@ void InteractiveCli::moveEntry(const string &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::readField(const string &fieldName)
|
void InteractiveCli::readField(const std::string &fieldName)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not read field; no file open" << endl;
|
m_o << "can not read field; no file open" << endl;
|
||||||
|
@ -571,7 +581,7 @@ void InteractiveCli::readField(const string &fieldName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::setField(bool useMuter, const string &fieldName)
|
void InteractiveCli::setField(bool useMuter, const std::string &fieldName)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not set field; no file open" << endl;
|
m_o << "can not set field; no file open" << endl;
|
||||||
|
@ -581,22 +591,22 @@ void InteractiveCli::setField(bool useMuter, const string &fieldName)
|
||||||
m_o << "can not set field; current entry is no account entry" << endl;
|
m_o << "can not set field; current entry is no account entry" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vector<Field> &fields = static_cast<AccountEntry *>(m_currentEntry)->fields();
|
auto &fields = static_cast<AccountEntry *>(m_currentEntry)->fields();
|
||||||
unsigned int valuesFound = 0;
|
auto valuesFound = unsigned();
|
||||||
string value;
|
auto value = std::string();
|
||||||
m_o << "enter new value: ";
|
m_o << "enter new value: ";
|
||||||
if (useMuter) {
|
if (useMuter) {
|
||||||
InputMuter m;
|
InputMuter m;
|
||||||
getline(m_i, value);
|
std::getline(m_i, value);
|
||||||
m_o << endl << "repeat: ";
|
m_o << endl << "repeat: ";
|
||||||
string repeat;
|
auto repeat = std::string();
|
||||||
getline(m_i, repeat);
|
std::getline(m_i, repeat);
|
||||||
if (value != repeat) {
|
if (value != repeat) {
|
||||||
m_o << "values do not match; field has not been altered" << endl;
|
m_o << "values do not match; field has not been altered" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getline(m_i, value);
|
std::getline(m_i, value);
|
||||||
}
|
}
|
||||||
for (Field &field : fields) {
|
for (Field &field : fields) {
|
||||||
if (field.name() == fieldName) {
|
if (field.name() == fieldName) {
|
||||||
|
@ -643,7 +653,7 @@ void InteractiveCli::setField(bool useMuter, const string &fieldName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveCli::removeField(const string &fieldName)
|
void InteractiveCli::removeField(const std::string &fieldName)
|
||||||
{
|
{
|
||||||
if (!m_file.isOpen()) {
|
if (!m_file.isOpen()) {
|
||||||
m_o << "can not remove field; no file open" << endl;
|
m_o << "can not remove field; no file open" << endl;
|
||||||
|
@ -653,8 +663,8 @@ void InteractiveCli::removeField(const string &fieldName)
|
||||||
m_o << "can not remove field; current entry is no account entry" << endl;
|
m_o << "can not remove field; current entry is no account entry" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vector<Field> &fields = static_cast<AccountEntry *>(m_currentEntry)->fields();
|
auto &fields = static_cast<AccountEntry *>(m_currentEntry)->fields();
|
||||||
unsigned int valuesFound = 0;
|
auto valuesFound = unsigned();
|
||||||
for (const Field &field : fields) {
|
for (const Field &field : fields) {
|
||||||
if (field.name() == fieldName) {
|
if (field.name() == fieldName) {
|
||||||
++valuesFound;
|
++valuesFound;
|
||||||
|
@ -730,7 +740,7 @@ void InteractiveCli::quit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string InteractiveCli::askForPassphrase(bool confirm)
|
std::string InteractiveCli::askForPassphrase(bool confirm)
|
||||||
{
|
{
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
m_o << "enter new passphrase: ";
|
m_o << "enter new passphrase: ";
|
||||||
|
@ -738,10 +748,10 @@ string InteractiveCli::askForPassphrase(bool confirm)
|
||||||
m_o << "enter passphrase: ";
|
m_o << "enter passphrase: ";
|
||||||
}
|
}
|
||||||
m_o.flush();
|
m_o.flush();
|
||||||
string input1;
|
auto input1 = std::string();
|
||||||
{
|
{
|
||||||
InputMuter m;
|
auto m = InputMuter();
|
||||||
getline(m_i, input1);
|
std::getline(m_i, input1);
|
||||||
}
|
}
|
||||||
m_o << endl;
|
m_o << endl;
|
||||||
if (input1.empty()) {
|
if (input1.empty()) {
|
||||||
|
@ -751,15 +761,15 @@ string InteractiveCli::askForPassphrase(bool confirm)
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
m_o << "confirm new passphrase: ";
|
m_o << "confirm new passphrase: ";
|
||||||
m_o.flush();
|
m_o.flush();
|
||||||
string input2;
|
auto input2 = std::string();
|
||||||
{
|
{
|
||||||
InputMuter m;
|
auto m = InputMuter();
|
||||||
getline(m_i, input2);
|
std::getline(m_i, input2);
|
||||||
}
|
}
|
||||||
m_o << endl;
|
m_o << endl;
|
||||||
if (input1 != input2) {
|
if (input1 != input2) {
|
||||||
m_o << "phrases do not match" << endl;
|
m_o << "phrases do not match" << endl;
|
||||||
throw runtime_error("confirmation failed");
|
throw std::runtime_error("confirmation failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return input1;
|
return input1;
|
||||||
|
|
11
cli/cli.h
11
cli/cli.h
|
@ -12,7 +12,7 @@
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <string_view>
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
class Entry;
|
class Entry;
|
||||||
|
@ -23,7 +23,7 @@ namespace Cli {
|
||||||
|
|
||||||
class InputMuter {
|
class InputMuter {
|
||||||
public:
|
public:
|
||||||
InputMuter();
|
explicit InputMuter();
|
||||||
~InputMuter();
|
~InputMuter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -39,9 +39,10 @@ void clearConsole();
|
||||||
|
|
||||||
class InteractiveCli {
|
class InteractiveCli {
|
||||||
public:
|
public:
|
||||||
InteractiveCli();
|
explicit InteractiveCli();
|
||||||
void run(const std::string &file = std::string());
|
~InteractiveCli();
|
||||||
void openFile(const std::string &file, Io::PasswordFileOpenFlags openFlags);
|
int run(std::string_view file);
|
||||||
|
void openFile(std::string_view file, Io::PasswordFileOpenFlags openFlags);
|
||||||
void closeFile();
|
void closeFile();
|
||||||
void saveFile();
|
void saveFile();
|
||||||
void createFile(const std::string &file);
|
void createFile(const std::string &file);
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace QtGui {
|
||||||
|
|
||||||
class FieldDelegate : public QStyledItemDelegate {
|
class FieldDelegate : public QStyledItemDelegate {
|
||||||
public:
|
public:
|
||||||
FieldDelegate(QObject *parent = nullptr);
|
explicit FieldDelegate(QObject *parent = nullptr);
|
||||||
|
|
||||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,8 @@ int runWidgetsGui(int argc, char *argv[], const QtConfigArguments &qtConfigArgs,
|
||||||
OpenSsl::init();
|
OpenSsl::init();
|
||||||
|
|
||||||
// init application
|
// init application
|
||||||
QApplication application(argc, argv);
|
auto application = QApplication(argc, argv);
|
||||||
|
QObject::connect(&application, &QCoreApplication::aboutToQuit, &OpenSsl::clean);
|
||||||
|
|
||||||
// restore Qt settings
|
// restore Qt settings
|
||||||
auto qtSettings = QtSettings();
|
auto qtSettings = QtSettings();
|
||||||
|
@ -56,7 +57,6 @@ int runWidgetsGui(int argc, char *argv[], const QtConfigArguments &qtConfigArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// start event loop
|
// start event loop
|
||||||
QObject::connect(&application, &QCoreApplication::aboutToQuit, &OpenSsl::clean);
|
|
||||||
auto res = application.exec();
|
auto res = application.exec();
|
||||||
|
|
||||||
// save settings to disk
|
// save settings to disk
|
||||||
|
|
|
@ -17,7 +17,7 @@ class StackSupport {
|
||||||
friend class StackAbsorper;
|
friend class StackAbsorper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StackSupport(QUndoStack *undoStack = nullptr);
|
explicit StackSupport(QUndoStack *undoStack = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QUndoStack *undoStack();
|
QUndoStack *undoStack();
|
||||||
|
@ -68,7 +68,7 @@ inline void StackSupport::clearUndoStack()
|
||||||
*/
|
*/
|
||||||
class StackAbsorper {
|
class StackAbsorper {
|
||||||
public:
|
public:
|
||||||
StackAbsorper(StackSupport *supported);
|
explicit StackAbsorper(StackSupport *supported);
|
||||||
~StackAbsorper();
|
~StackAbsorper();
|
||||||
QUndoStack *stack();
|
QUndoStack *stack();
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,15 @@ void CustomUndoCommand::undo()
|
||||||
* \brief Sets the value for the specified index and role in the specified field model.
|
* \brief Sets the value for the specified index and role in the specified field model.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// \cond
|
||||||
|
|
||||||
|
static QString getFieldName(FieldModel *model, int row, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
return model->index(row, 0, index.parent()).data().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new command.
|
* \brief Constructs a new command.
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +84,6 @@ FieldModelSetValueCommand::FieldModelSetValueCommand(FieldModel *model, const QM
|
||||||
, m_oldValue(model->data(index, role))
|
, m_oldValue(model->data(index, role))
|
||||||
, m_role(role)
|
, m_role(role)
|
||||||
{
|
{
|
||||||
QString fieldName = model->index(m_row, 0, index.parent()).data().toString();
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
case Qt::EditRole:
|
case Qt::EditRole:
|
||||||
|
@ -88,16 +96,16 @@ FieldModelSetValueCommand::FieldModelSetValueCommand(FieldModel *model, const QM
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (fieldName.isEmpty()) {
|
if (const auto fieldName = getFieldName(model, m_row, index); !fieldName.isEmpty()) {
|
||||||
setText(QApplication::translate("undocommands", "setting value of empty field"));
|
|
||||||
} else {
|
|
||||||
setText(QApplication::translate("undocommands", "setting value of »%1« field").arg(fieldName));
|
setText(QApplication::translate("undocommands", "setting value of »%1« field").arg(fieldName));
|
||||||
|
} else {
|
||||||
|
setText(QApplication::translate("undocommands", "setting value of empty field"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FieldTypeRole:
|
case FieldTypeRole:
|
||||||
setText(QApplication::translate("undocommands", "setting type of »%1« field").arg(fieldName));
|
setText(QApplication::translate("undocommands", "setting type of »%1« field").arg(getFieldName(model, m_row, index)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setText(QApplication::translate("undocommands", "setting field property in row »%1«").arg(m_row + 1));
|
setText(QApplication::translate("undocommands", "setting field property in row »%1«").arg(m_row + 1));
|
||||||
|
@ -316,7 +324,7 @@ EntryModelModifyRowsCommand::~EntryModelModifyRowsCommand()
|
||||||
*/
|
*/
|
||||||
bool EntryModelModifyRowsCommand::insert()
|
bool EntryModelModifyRowsCommand::insert()
|
||||||
{
|
{
|
||||||
if (Entry *parentEntry = entryFromPathCpy(m_model, m_parentPath)) {
|
if (Entry *const parentEntry = entryFromPathCpy(m_model, m_parentPath)) {
|
||||||
if (m_model->insertEntries(m_row, m_model->index(parentEntry), m_values)) {
|
if (m_model->insertEntries(m_row, m_model->index(parentEntry), m_values)) {
|
||||||
m_values.clear();
|
m_values.clear();
|
||||||
return true;
|
return true;
|
||||||
|
@ -334,7 +342,7 @@ bool EntryModelModifyRowsCommand::insert()
|
||||||
*/
|
*/
|
||||||
bool EntryModelModifyRowsCommand::remove()
|
bool EntryModelModifyRowsCommand::remove()
|
||||||
{
|
{
|
||||||
if (Entry *parentEntry = entryFromPathCpy(m_model, m_parentPath)) {
|
if (Entry *const parentEntry = entryFromPathCpy(m_model, m_parentPath)) {
|
||||||
m_values = m_model->takeEntries(m_row, m_count, m_model->index(parentEntry));
|
m_values = m_model->takeEntries(m_row, m_count, m_model->index(parentEntry));
|
||||||
return !m_values.isEmpty();
|
return !m_values.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -433,29 +441,28 @@ bool EntryModelMoveRowsCommand::internalRedo()
|
||||||
|
|
||||||
bool EntryModelMoveRowsCommand::internalUndo()
|
bool EntryModelMoveRowsCommand::internalUndo()
|
||||||
{
|
{
|
||||||
if (m_count) {
|
if (!m_count) {
|
||||||
Entry *sourceParentEntry = entryFromPathCpy(m_model, m_sourceParentPath);
|
return true;
|
||||||
Entry *destParentEntry = entryFromPathCpy(m_model, m_destParentPath);
|
|
||||||
if (sourceParentEntry && destParentEntry) {
|
|
||||||
int sourceRow = m_destChild;
|
|
||||||
int destChild = m_sourceRow;
|
|
||||||
// moves within the same parent needs special consideration
|
|
||||||
if (sourceParentEntry == destParentEntry) {
|
|
||||||
// move entry down
|
|
||||||
if (m_sourceRow < m_destChild) {
|
|
||||||
sourceRow -= m_count;
|
|
||||||
// move entry up
|
|
||||||
} else if (m_sourceRow > m_destChild) {
|
|
||||||
destChild += m_count;
|
|
||||||
// keep entry were it is
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m_model->moveRows(m_model->index(destParentEntry), sourceRow, m_count, m_model->index(sourceParentEntry), destChild);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
Entry *const sourceParentEntry = entryFromPathCpy(m_model, m_sourceParentPath);
|
||||||
|
Entry *const destParentEntry = entryFromPathCpy(m_model, m_destParentPath);
|
||||||
|
if (sourceParentEntry && destParentEntry) {
|
||||||
|
auto sourceRow = m_destChild, destChild = m_sourceRow;
|
||||||
|
// moves within the same parent needs special consideration
|
||||||
|
if (sourceParentEntry == destParentEntry) {
|
||||||
|
// move entry down
|
||||||
|
if (m_sourceRow < m_destChild) {
|
||||||
|
sourceRow -= m_count;
|
||||||
|
// move entry up
|
||||||
|
} else if (m_sourceRow > m_destChild) {
|
||||||
|
destChild += m_count;
|
||||||
|
// keep entry were it is
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_model->moveRows(m_model->index(destParentEntry), sourceRow, m_count, m_model->index(sourceParentEntry), destChild);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace QtGui
|
} // namespace QtGui
|
||||||
|
|
83
main.cpp
83
main.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include "./cli/cli.h"
|
#include "./cli/cli.h"
|
||||||
|
|
||||||
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS
|
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS
|
||||||
#include "./gui/initiategui.h"
|
#include "./gui/initiategui.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,13 +10,12 @@
|
||||||
#include "resources/config.h"
|
#include "resources/config.h"
|
||||||
#include "resources/qtconfig.h"
|
#include "resources/qtconfig.h"
|
||||||
|
|
||||||
#include <passwordfile/util/openssl.h>
|
|
||||||
|
|
||||||
#include <c++utilities/application/argumentparser.h>
|
#include <c++utilities/application/argumentparser.h>
|
||||||
#include <c++utilities/application/commandlineutils.h>
|
#include <c++utilities/application/commandlineutils.h>
|
||||||
#include <c++utilities/misc/parseerror.h>
|
#include <c++utilities/misc/parseerror.h>
|
||||||
|
|
||||||
#if defined(PASSWORD_MANAGER_GUI_QTWIDGETS) || defined(PASSWORD_MANAGER_GUI_QTQUICK)
|
#if defined(PASSWORD_MANAGER_GUI_QTWIDGETS) || defined(PASSWORD_MANAGER_GUI_QTQUICK)
|
||||||
|
#define PASSWORD_MANAGER_GUI_QTWIDGETS_OR_QTQUICK
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <qtutilities/resources/qtconfigarguments.h>
|
#include <qtutilities/resources/qtconfigarguments.h>
|
||||||
|
@ -24,33 +24,39 @@ ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES
|
||||||
#include <c++utilities/application/fakeqtconfigarguments.h>
|
#include <c++utilities/application/fakeqtconfigarguments.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// force (preferably Qt Quick) GUI under Android
|
// force (preferably Qt Quick) GUI under Android
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#if defined(PASSWORD_MANAGER_GUI_QTWIDGETS) || defined(PASSWORD_MANAGER_GUI_QTQUICK)
|
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS_OR_QTQUICK
|
||||||
#define PASSWORD_MANAGER_FORCE_GUI
|
#define PASSWORD_MANAGER_FORCE_GUI
|
||||||
#else
|
#else
|
||||||
#error "Must build at least one kind of GUI under Android."
|
#error "Must configure building at least one kind of GUI under Android."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace CppUtilities;
|
using namespace CppUtilities;
|
||||||
using namespace Util;
|
|
||||||
|
#ifndef PASSWORD_MANAGER_FORCE_GUI
|
||||||
|
static int fail(std::string_view error)
|
||||||
|
{
|
||||||
|
CMD_UTILS_START_CONSOLE;
|
||||||
|
std::cerr << error << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
CMD_UTILS_CONVERT_ARGS_TO_UTF8;
|
CMD_UTILS_CONVERT_ARGS_TO_UTF8;
|
||||||
SET_APPLICATION_INFO;
|
SET_APPLICATION_INFO;
|
||||||
QT_CONFIG_ARGUMENTS qtConfigArgs;
|
|
||||||
int returnCode = 0;
|
|
||||||
|
|
||||||
|
// parse CLI arguments
|
||||||
|
auto qtConfigArgs = QT_CONFIG_ARGUMENTS();
|
||||||
#ifndef PASSWORD_MANAGER_FORCE_GUI
|
#ifndef PASSWORD_MANAGER_FORCE_GUI
|
||||||
// setup argument parser
|
auto parser = ArgumentParser();
|
||||||
ArgumentParser parser;
|
auto fileArg = Argument("file", 'f', "specifies the file to be opened (or created when using --modify)");
|
||||||
// file argument
|
|
||||||
Argument fileArg("file", 'f', "specifies the file to be opened (or created when using --modify)");
|
|
||||||
fileArg.setValueNames({ "path" });
|
fileArg.setValueNames({ "path" });
|
||||||
fileArg.setRequiredValueCount(1);
|
fileArg.setRequiredValueCount(1);
|
||||||
fileArg.setCombinable(true);
|
fileArg.setCombinable(true);
|
||||||
|
@ -58,63 +64,44 @@ int main(int argc, char *argv[])
|
||||||
fileArg.setImplicit(true);
|
fileArg.setImplicit(true);
|
||||||
qtConfigArgs.qtWidgetsGuiArg().addSubArgument(&fileArg);
|
qtConfigArgs.qtWidgetsGuiArg().addSubArgument(&fileArg);
|
||||||
qtConfigArgs.qtQuickGuiArg().addSubArgument(&fileArg);
|
qtConfigArgs.qtQuickGuiArg().addSubArgument(&fileArg);
|
||||||
// cli argument
|
auto cliArg = Argument("interactive-cli", 'i', "starts the interactive command line interface");
|
||||||
Argument cliArg("interactive-cli", 'i', "starts the interactive command line interface");
|
|
||||||
cliArg.setDenotesOperation(true);
|
cliArg.setDenotesOperation(true);
|
||||||
cliArg.setSubArguments({ &fileArg });
|
cliArg.setSubArguments({ &fileArg });
|
||||||
// help argument
|
auto helpArg = HelpArgument(parser);
|
||||||
HelpArgument helpArg(parser);
|
|
||||||
parser.setMainArguments({ &qtConfigArgs.qtWidgetsGuiArg(), &qtConfigArgs.qtQuickGuiArg(), &cliArg, &helpArg });
|
parser.setMainArguments({ &qtConfigArgs.qtWidgetsGuiArg(), &qtConfigArgs.qtQuickGuiArg(), &cliArg, &helpArg });
|
||||||
// parse the specified arguments
|
|
||||||
parser.parseArgs(argc, argv);
|
parser.parseArgs(argc, argv);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PASSWORD_MANAGER_FORCE_GUI
|
// run CLI if CLI-argument is present
|
||||||
// start either interactive CLI or GUI
|
|
||||||
if (cliArg.isPresent()) {
|
if (cliArg.isPresent()) {
|
||||||
// init OpenSSL
|
return Cli::InteractiveCli().run(fileArg.isPresent() ? std::string(fileArg.firstValue()) : std::string());
|
||||||
OpenSsl::init();
|
}
|
||||||
|
|
||||||
Cli::InteractiveCli cli;
|
// run GUI depending on which GUI-argument is present
|
||||||
if (fileArg.isPresent()) {
|
if (qtConfigArgs.areQtGuiArgsPresent()) {
|
||||||
cli.run(fileArg.firstValue());
|
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS_OR_QTQUICK
|
||||||
} else {
|
const auto file = fileArg.isPresent() ? QString::fromLocal8Bit(fileArg.firstValue()) : QString();
|
||||||
cli.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean OpenSSL
|
|
||||||
OpenSsl::clean();
|
|
||||||
|
|
||||||
} else if (qtConfigArgs.areQtGuiArgsPresent()) {
|
|
||||||
#if defined(PASSWORD_MANAGER_GUI_QTWIDGETS) || defined(PASSWORD_MANAGER_GUI_QTQUICK)
|
|
||||||
const auto file(fileArg.isPresent() ? QString::fromLocal8Bit(fileArg.firstValue()) : QString());
|
|
||||||
#endif
|
#endif
|
||||||
if (qtConfigArgs.qtWidgetsGuiArg().isPresent()) {
|
if (qtConfigArgs.qtWidgetsGuiArg().isPresent()) {
|
||||||
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS
|
#ifdef PASSWORD_MANAGER_GUI_QTWIDGETS
|
||||||
returnCode = QtGui::runWidgetsGui(argc, argv, qtConfigArgs, file);
|
return QtGui::runWidgetsGui(argc, argv, qtConfigArgs, file);
|
||||||
#else
|
#else
|
||||||
CMD_UTILS_START_CONSOLE;
|
return fail("The application has not been built with Qt Widgets GUI support.");
|
||||||
cerr << "The application has not been built with Qt widgets support." << endl;
|
|
||||||
#endif
|
#endif
|
||||||
} else if (qtConfigArgs.qtQuickGuiArg().isPresent()) {
|
} else if (qtConfigArgs.qtQuickGuiArg().isPresent()) {
|
||||||
#ifdef PASSWORD_MANAGER_GUI_QTQUICK
|
#ifdef PASSWORD_MANAGER_GUI_QTQUICK
|
||||||
returnCode = QtGui::runQuickGui(argc, argv, qtConfigArgs, file);
|
return QtGui::runQuickGui(argc, argv, qtConfigArgs, file);
|
||||||
#else
|
#else
|
||||||
CMD_UTILS_START_CONSOLE;
|
return fail("The application has not been built with Qt Quick GUI support.");
|
||||||
cerr << "The application has not been built with Qt quick support." << endl;
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
CMD_UTILS_START_CONSOLE;
|
|
||||||
cerr << "See --help for usage." << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return fail("See --help for usage.");
|
||||||
|
|
||||||
#else // PASSWORD_MANAGER_FORCE_GUI
|
#else // PASSWORD_MANAGER_FORCE_GUI
|
||||||
#ifdef PASSWORD_MANAGER_GUI_QTQUICK
|
#ifdef PASSWORD_MANAGER_GUI_QTQUICK
|
||||||
returnCode = QtGui::runQuickGui(argc, argv, qtConfigArgs, QString());
|
return QtGui::runQuickGui(argc, argv, qtConfigArgs, QString());
|
||||||
#else
|
#else
|
||||||
returnCode = QtGui::runWidgetsGui(argc, argv, qtConfigArgs, QString());
|
return QtGui::runWidgetsGui(argc, argv, qtConfigArgs, QString());
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return returnCode;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ bool FieldModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int co
|
||||||
|
|
||||||
// reserve space for temporary copies (FIXME: possible to avoid this?)
|
// reserve space for temporary copies (FIXME: possible to avoid this?)
|
||||||
m_fields->reserve(m_fields->size() + static_cast<std::size_t>(count));
|
m_fields->reserve(m_fields->size() + static_cast<std::size_t>(count));
|
||||||
auto tmp = vector<Io::Field>(static_cast<std::size_t>(count));
|
auto tmp = std::vector<Io::Field>(static_cast<std::size_t>(count));
|
||||||
// move rows to temporary array
|
// move rows to temporary array
|
||||||
std::move(m_fields->begin() + sourceRow, m_fields->begin() + sourceRow + count, tmp.begin());
|
std::move(m_fields->begin() + sourceRow, m_fields->begin() + sourceRow + count, tmp.begin());
|
||||||
// erase slots of rows to be moved
|
// erase slots of rows to be moved
|
||||||
|
@ -394,10 +394,7 @@ QMimeData *FieldModel::mimeData(const QModelIndexList &indices) const
|
||||||
*/
|
*/
|
||||||
const Field *FieldModel::field(size_t row) const
|
const Field *FieldModel::field(size_t row) const
|
||||||
{
|
{
|
||||||
if (m_fields && row < m_fields->size()) {
|
return m_fields && row < m_fields->size() ? &(*m_fields)[row] : nullptr;
|
||||||
return &(*m_fields)[row];
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QtGui
|
} // namespace QtGui
|
||||||
|
|
Loading…
Reference in New Issue