1
0
mirror of https://github.com/QRouland/UTPass.git synced 2025-07-09 05:12:29 +00:00

Add search password feature (equivalent to pass find)

This commit is contained in:
2025-02-05 11:02:59 +01:00
parent e47d50072a
commit 2409f33f59
13 changed files with 250 additions and 89 deletions

View File

@ -6,15 +6,33 @@ import Lomiri.Components.Themes 1.3
import Pass 1.0
import QtQuick 2.4
Component {
Item {
//property string folder
id: fileDir
property string fName
property bool fIsDir
property bool commonBorder: true
property int lBorderwidth: 0
property int rBorderwidth: 0
property int tBorderwidth: 0
property int bBorderwidth: 0
property int commonBorderWidth: 0
property string borderColor: LomiriColors.warmGrey
signal clicked()
anchors.right: parent.right
anchors.left: parent.left
height: units.gu(5)
Rectangle {
anchors.right: parent.right
anchors.left: parent.left
height: units.gu(5)
anchors.fill: parent
color: theme.palette.normal.background
Text {
text: fileIsDir ? fileName : fileName.slice(0, -4) // remove .gpg if it's a file
text: fileDir.fIsDir ? fileDir.fName : fileDir.fName.slice(0, -4) // remove .gpg if it's a file
anchors.left: parent.left
anchors.leftMargin: units.gu(2)
anchors.verticalCenter: parent.verticalCenter
@ -26,32 +44,36 @@ Component {
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: units.gu(2)
height: units.gu(4)
name: fileIsDir ? "go-next" : "lock"
name: fileDir.fIsDir ? "go-next" : "lock"
color: LomiriColors.orange
}
MouseArea {
// onClicked: {
// var path = fileDir.fdfolder + "/" + fileName;
// if (fileIsDir) {
// fileDir.fdfolder = path;
// //backAction.visible = true;
// // passwordListHeader.title = fileName;
// } else {
// console.debug("pass show %1".arg(path));
// Pass.show(path);
// }
// }
anchors.fill: parent
onClicked: {
var path = folderModel.folder + "/" + fileName;
if (fileIsDir) {
folderModel.folder = path;
backAction.visible = true;
passwordListHeader.title = fileName;
} else {
console.debug("pass show %1".arg(path));
Pass.show(path);
}
}
onClicked: fileDir.clicked()
}
CustomBorder {
commonBorder: false
lBorderwidth: 0
rBorderwidth: 0
tBorderwidth: 0
bBorderwidth: 1
borderColor: LomiriColors.warmGrey
id: cb
commonBorder: fileDir.commonBorder
lBorderwidth: fileDir.lBorderwidth
rBorderwidth: fileDir.rBorderwidth
tBorderwidth: fileDir.tBorderwidth
bBorderwidth: fileDir.bBorderwidth
borderColor: fileDir.borderColor
}
}

View File

@ -10,11 +10,36 @@ import "headers"
Page {
id: passwordListPage
property string passwordStorePath
property string __passwordStorePath
property var __passwords
function __searchPasswords(filter) {
var ret = [];
if (__passwords) {
for (var i = 0; i < __passwords.length; i++) {
if (__passwords[i].toUpperCase().indexOf(filter.toUpperCase()) > -1)
ret.push(__passwords[i]);
}
}
return ret;
}
function __searchUpdateModel(text) {
var ret = __searchPasswords(text);
passwordListSearch.model.clear();
for (var i = 0; i < ret.length; i++) {
if (ret[i])
passwordListSearch.model.append({
"fileName": ret[i]
});
}
}
anchors.fill: parent
Component.onCompleted: {
passwordStorePath = "file:" + Pass.password_store;
__passwordStorePath = "file:" + Pass.password_store;
Pass.onShowSucceed.connect(function(filename, text) {
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), {
"plainText": text,
@ -24,16 +49,22 @@ Page {
Pass.onShowFailed.connect(function(message) {
PopupUtils.open(passwordPageDecryptError);
});
Pass.onLsSucceed.connect(function(passwords) {
__passwords = passwords;
});
Pass.ls();
}
Column {
id: passwordListEmpty
anchors.top: passwordListHeader.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.leftMargin: units.gu(2)
anchors.rightMargin: units.gu(2)
visible: folderModel.count == 0
visible: passwordListNav.model.count === 0
Rectangle {
width: parent.width
@ -71,24 +102,66 @@ Page {
}
ListView {
id: passwordListNav
anchors.top: passwordListHeader.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
spacing: 1
visible: folderModel.count != 0
visible: passwordListNav.model.count !== 0 && passwordListHeader.searchBarIsActive
model: FolderListModel {
id: folderModel
nameFilters: ["*.gpg"]
rootFolder: passwordStorePath
folder: passwordStorePath
rootFolder: __passwordStorePath
folder: __passwordStorePath
showDirs: true
}
delegate: FileDir {
id: fileDelegate
delegate: Component {
FileDir {
fName: fileName
fIsDir: fileIsDir
onClicked: {
var path = passwordListNav.model.folder + "/" + fileName;
if (fileIsDir) {
passwordListNav.model.folder = path;
backAction.visible = true;
passwordListHeader.title = fileName;
} else {
console.debug("pass show %1".arg(path));
Pass.show(path);
}
}
}
}
}
ListView {
id: passwordListSearch
anchors.top: passwordListHeader.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
visible: passwordListNav.model.count !== 0 && !passwordListHeader.searchBarIsActive
model: ListModel {
}
delegate: Component {
FileDir {
fName: fileName
fIsDir: false
onClicked: {
var path = __passwordStorePath + "/" + fileName;
console.debug("pass show %1".arg(path));
Pass.show(path);
}
}
}
}
@ -105,6 +178,8 @@ Page {
header: MainHeader {
id: passwordListHeader
onSearchBarActived: __searchUpdateModel("")
onSearchBarTextChanged: __searchUpdateModel(text)
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
@ -114,9 +189,9 @@ Page {
text: i18n.tr("Back")
visible: false
onTriggered: {
folderModel.folder = folderModel.parentFolder;
console.debug(folderModel.folder);
if (folderModel.rootFolder === folderModel.folder) {
passwordListNav.model.folder = passwordListNav.model.parentFolder;
console.debug(passwordListNav.model.folder);
if (passwordListNav.model.rootFolder === passwordListNav.model.folder) {
backAction.visible = false;
passwordListHeader.title = i18n.tr("UTPass");
} else {

View File

@ -4,23 +4,29 @@ import QtQuick 2.4
PageHeader {
id: mainHeader
readonly property bool searchBarIsActive: !searchBar.visible
signal searchBarActived()
signal searchBarTextChanged(string text)
width: parent.width
height: units.gu(6)
title: i18n.tr("UTPass")
trailingActionBar.height: units.gu(4)
trailingActionBar.numberOfSlots: 2
trailingActionBar.actions: [
/*Action { TODO
iconName: "search"
Action {
iconName: searchBarIsActive ? "search" : "close"
text: i18n.tr("Search")
onTriggered: {
searchBar.visible = !searchBar.visible
labelTitle.visible = !searchBar.visible
searchBar.visible = !searchBar.visible;
labelTitle.visible = !searchBar.visible;
if (searchBar.visible === true) {
searchBar.focus = true
searchBar.focus = true;
searchBarActived();
}
}
},*/
},
Action {
iconName: "settings"
text: i18n.tr("Settings")
@ -58,8 +64,7 @@ PageHeader {
height: units.gu(4)
visible: false
anchors.verticalCenter: parent.verticalCenter
onFocusChanged: {
}
onContentWidthChanged: searchBarTextChanged(searchBar.text)
}
}