Allow to cut & paste entries in Qt Quick GUI

This commit is contained in:
Martchus 2018-06-11 23:21:15 +02:00
parent d364941c28
commit 3fd7a474ae
3 changed files with 96 additions and 25 deletions

View File

@ -16,27 +16,18 @@ Kirigami.ScrollablePage {
main: Kirigami.Action {
iconName: "list-add"
text: qsTr("Add account")
onTriggered: {
model.setInsertTypeToAccount()
model.insertRows(model.rowCount(rootIndex), 1, rootIndex)
}
onTriggered: insertEntry("Account")
}
left: Kirigami.Action {
iconName: "edit-paste"
text: qsTr("Paste account")
onTriggered: {
// TODO
}
enabled: nativeInterface.canPaste
onTriggered: nativeInterface.pasteEntries(rootIndex)
}
right: Kirigami.Action {
iconName: "folder-add"
text: qsTr("Add category")
onTriggered: {
model.setInsertTypeToNode()
model.insertRows(model.rowCount(rootIndex), 1, rootIndex)
}
onTriggered: insertEntry("Node")
}
}
onBackRequested: {
@ -51,31 +42,44 @@ Kirigami.ScrollablePage {
BasicDialog {
id: confirmDeletionDialog
property string entryDesc: "?"
property int entryIndex: -1
standardButtons: Controls.Dialog.Ok | Controls.Dialog.Cancel
title: qsTr("Delete %1?").arg(entryDesc)
onAccepted: model.removeRows(this.entryIndex, 1, rootIndex)
function confirmDeletion(entryName, entryIndex) {
var isNode = model.isNode(entryIndex)
var isNode = model.isNode(model.index(entryIndex, 0, rootIndex))
var entryType = isNode ? qsTr("category ") : qsTr("account ")
this.entryIndex = entryIndex
this.entryDesc = entryType + entryName
this.open()
}
onAccepted: model.removeRows(this.entryIndex, 1, rootIndex)
}
BasicDialog {
id: renameDialog
property string entryDesc: "?"
property int entryIndex: -1
property alias newEntryName: entryNameTextField.text
property bool entryNew: false
standardButtons: newEntryName.length
> 0 ? Controls.Dialog.Ok | Controls.Dialog.Cancel : Controls.Dialog.Cancel
title: qsTr("Rename ") + entryDesc
title: (entryNew ? qsTr("Name for new ") : qsTr("Rename ")) + entryDesc
onAccepted: {
model.setData(model.index(this.entryIndex, 0, rootIndex),
newEntryName)
}
onRejected: {
if (this.entryNew) {
model.removeRows(this.entryIndex, 1, rootIndex)
}
}
ColumnLayout {
Controls.TextField {
@ -86,17 +90,20 @@ Kirigami.ScrollablePage {
}
function renameEntry(entryName, entryIndex) {
var isNode = model.isNode(entryIndex)
var isNode = model.isNode(model.index(entryIndex, 0, rootIndex))
var entryType = isNode ? qsTr("category ") : qsTr("account ")
this.entryIndex = entryIndex
this.entryDesc = entryType + entryName
this.newEntryName = entryName
this.entryNew = entryName === null
if (this.entryNew) {
this.entryDesc = entryType
this.newEntryName = ""
} else {
this.entryDesc = entryType + entryName
this.newEntryName = entryName
}
this.open()
}
onAccepted: model.setData(model.index(this.entryIndex, 0, rootIndex),
newEntryName)
}
// "sheet" to display field model
@ -163,7 +170,6 @@ Kirigami.ScrollablePage {
Layout.fillHeight: true
height: Math.max(implicitHeight,
Kirigami.Units.iconSizes.smallMedium)
Layout.alignment: verticalCenter
text: name
MouseArea {
@ -177,7 +183,11 @@ Kirigami.ScrollablePage {
Kirigami.Action {
iconName: "edit-cut"
text: qsTr("Cut")
onTriggered: showPassiveNotification(text + " " + name)
onTriggered: {
nativeInterface.cutEntry(delegateModel.model.index(
index, 0, rootIndex))
showPassiveNotification(text + " " + name)
}
},
Kirigami.Action {
iconName: "edit-delete"
@ -194,4 +204,11 @@ Kirigami.ScrollablePage {
}
}
}
function insertEntry(entryType) {
var newIndex = model.rowCount(rootIndex)
model["setInsertTypeTo" + entryType]()
model.insertRows(newIndex, 1, rootIndex)
renameDialog.renameEntry(null, newIndex)
}
}

View File

@ -112,6 +112,30 @@ void Controller::save()
}
}
bool Controller::pasteEntries(const QModelIndex &destinationParent, int row)
{
if (m_cutEntries.isEmpty() || !m_entryModel.isNode(destinationParent)) {
return false;
}
if (row < 0) {
row = m_entryModel.rowCount(destinationParent);
}
bool result = true;
for (const QPersistentModelIndex &cutIndex : m_cutEntries) {
if (m_entryModel.moveRows(cutIndex.parent(), cutIndex.row(), 1, destinationParent, row)) {
++row;
} else {
result = false;
}
}
// clear the cut entries
m_cutEntries.clear();
emit cutEntriesChanged(m_cutEntries);
return true;
}
void Controller::resetFileStatus()
{
setFileOpen(false);

View File

@ -8,6 +8,7 @@
#include <passwordfile/io/passwordfile.h>
#include <QObject>
#include <QPersistentModelIndex>
namespace QtGui {
@ -22,6 +23,8 @@ class Controller : public QObject {
Q_PROPERTY(FieldModel *fieldModel READ fieldModel NOTIFY fieldModelChanged)
Q_PROPERTY(QModelIndex currentAccountIndex READ currentAccountIndex WRITE setCurrentAccountIndex NOTIFY currentAccountChanged)
Q_PROPERTY(QString currentAccountName READ currentAccountName NOTIFY currentAccountChanged)
Q_PROPERTY(QList<QPersistentModelIndex> cutEntries READ cutEntries WRITE setCutEntries NOTIFY cutEntriesChanged)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY cutEntriesChanged)
public:
explicit Controller(const QString &filePath = QString(), QObject *parent = nullptr);
@ -37,7 +40,12 @@ public:
FieldModel *fieldModel();
QModelIndex currentAccountIndex() const;
void setCurrentAccountIndex(const QModelIndex &accountIndex);
const QList<QPersistentModelIndex> &cutEntries() const;
void setCutEntries(const QList<QPersistentModelIndex> &cutEntries);
QString currentAccountName() const;
Q_INVOKABLE void cutEntry(const QModelIndex &entryIndex);
Q_INVOKABLE bool pasteEntries(const QModelIndex &destinationParent, int row = -1);
bool canPaste() const;
public slots:
void load();
@ -56,6 +64,7 @@ signals:
void entryFilterModelChanged();
void fieldModelChanged();
void currentAccountChanged();
void cutEntriesChanged(const QList<QPersistentModelIndex> &cutEntries);
private:
void resetFileStatus();
@ -70,6 +79,7 @@ private:
EntryModel m_entryModel;
EntryFilterModel m_entryFilterModel;
FieldModel m_fieldModel;
QList<QPersistentModelIndex> m_cutEntries;
bool m_fileOpen;
bool m_fileModified;
};
@ -120,11 +130,31 @@ inline void Controller::setCurrentAccountIndex(const QModelIndex &accountIndex)
emit currentAccountChanged();
}
inline const QList<QPersistentModelIndex> &Controller::cutEntries() const
{
return m_cutEntries;
}
inline void Controller::setCutEntries(const QList<QPersistentModelIndex> &cutEntries)
{
cutEntriesChanged(m_cutEntries = cutEntries);
}
inline QString Controller::currentAccountName() const
{
return m_fieldModel.accountEntry() ? QString::fromStdString(m_fieldModel.accountEntry()->label()) : QStringLiteral("?");
}
inline void Controller::cutEntry(const QModelIndex &entryIndex)
{
cutEntriesChanged(m_cutEntries << QPersistentModelIndex(entryIndex));
}
inline bool Controller::canPaste() const
{
return !m_cutEntries.isEmpty();
}
} // namespace QtGui
#endif // QT_QUICK_GUI_CONTROLLER_H