Allow to cut & paste entries in Qt Quick GUI
This commit is contained in:
parent
d364941c28
commit
3fd7a474ae
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue