blob: 1195ef89e5f99989bc0dbd8b696dfc75e36f52ee (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
import QtQuick 2.6
import Sailfish.Silica 1.0
import "../components"
Page {
id: mainPage
readonly property var isBackground : Qt.application.state
onIsBackgroundChanged: {
if(isBackground === Qt.ApplicationInactive) {
mainFlickable.restart_timers();
}
}
SilicaFlickable {
id: mainFlickable
anchors.fill: parent
contentHeight: column.height
function store_settings_with_error_message() {
var worked = passwordmaker.store_settings();
if(!worked) {
storeFailureNotice.show();
}
}
function restart_timers() {
if(autoClearMasterPasswordTimer.enabled && passwordmaker.master_password.length > 0) {
autoClearMasterPasswordTimer.restart();
}
if(autoClearGeneratedPasswordTimer.enabled && (passwordmaker.used_text.length > 0 || passwordmaker.url.length > 0)) {
autoClearGeneratedPasswordTimer.restart();
}
}
PullDownMenu {
MenuItem {
text: qsTr("App Settings")
onClicked: {
var pg = pageStack.animatorPush(Qt.resolvedUrl("SettingsEditor.qml"),
{
clear_generated_password : passwordmaker.settings.clear_generated_password_seconds,
clear_master_password : passwordmaker.settings.clear_master_password_seconds,
hide_generated_password : passwordmaker.settings.hide_generated_password
});
pg.pageCompleted.connect(function(pg) {
pg.accepted.connect(function() {
passwordmaker.settings.clear_generated_password_seconds
=pg.clear_generated_password;
passwordmaker.settings.clear_master_password_seconds
=pg.clear_master_password;
passwordmaker.settings.hide_generated_password
=pg.hide_generated_password;
mainFlickable.store_settings_with_error_message()
})
})
}
}
MenuItem {
text: qsTr("About")
onClicked: pageStack.animatorPush(Qt.resolvedUrl("AboutPage.qml"))
}
}
VerticalScrollDecorator {}
Column {
id: column
width: mainPage.width
spacing: Theme.paddingLarge
PageHeader {
title: qsTr("PassFish")
}
ValueButton {
id: profileButton
label: qsTr("Profile")
value: passwordmaker.profiles.current_profile_name
onClicked: pageStack.animatorPush(Qt.resolvedUrl("ProfilesPage.qml"))
}
TextField {
id: url
width: parent.width
text: passwordmaker.url
inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
label: qsTr("URL")
placeholderText: qsTr("URL")
EnterKey.iconSource: "image://theme/icon-m-enter-next"
EnterKey.onClicked: masterPassword.focus = true
Binding {
target: passwordmaker
property: "url"
value: url.text
}
}
PasswordField {
id: masterPassword
width: parent.width
text: passwordmaker.master_password
label: qsTr("Master Password")
placeholderText: qsTr("Master Password")
EnterKey.iconSource: "image://theme/icon-m-enter-close"
EnterKey.onClicked: focus = false
Binding {
target: passwordmaker
property: "master_password"
value: masterPassword.text
}
}
TextField {
id: usedText
width: parent.width
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
label: qsTr("Used Text")
hideLabelOnEmptyField: passwordmaker.used_text === ""
onFocusChanged: if(focus) text = passwordmaker.used_text
onPlaceholderTextChanged: if(!focus) text = ""
placeholderText: passwordmaker.used_text === "" ? qsTr("Used Text") : passwordmaker.used_text
EnterKey.iconSource: "image://theme/icon-m-enter-close"
EnterKey.onClicked: focus = false
Binding {
target: passwordmaker
property: "used_text"
value: usedText.text
when: usedText.focus
}
}
Separator {
width: parent.width
horizontalAlignment:Qt.AlignHCenter
color: Theme.secondaryColor
}
Row{
width: parent.width
PasswordField {
id: generatedPassword
width: parent.width - copyToClipboard.width
function password_text_from_generator_state(g, t, e) {
switch(g){
case 0 :
return e === TextInput.Normal ? t : t.replace(/./g, passwordCharacter);
case 1 :
return qsTr("Generating");
case 2 :
return qsTr("Missing text to use");
case 3 :
return qsTr("Missing master password");
case 4 :
return qsTr("Error in profile character list");
default:
return "";
}
}
passwordEchoMode: passwordmaker.settings.hide_generated_password
? TextInput.Password : TextInput.Normal
showEchoModeToggle: passwordmaker.settings.hide_generated_password
readOnly: true
focusOnClick: true
label: qsTr("Generated Password")
hideLabelOnEmptyField: false
placeholderText:
password_text_from_generator_state(
passwordmaker.generator_state
, passwordmaker.generated_password
, echoMode)
onFocusChanged: if(focus) text = passwordmaker.generated_password; else text = "";
placeholderColor: color
/*
//Commented out for now. This is anyhow never visible, and causes log spam on Sailfish 3.
BusyIndicator {
id: busy
parent: null
size: BusyIndicatorSize.Small
running: passwordmaker.generator_state === 1
}
states: State {
when: passwordmaker.generator_state === 1
PropertyChanges {
target: generatedPassword
rightItem: busy
}
}
*/
}
IconButton{
id: copyToClipboard
enabled: passwordmaker.generator_state === 0 && passwordmaker.generated_password.length > 0
icon.source: "image://theme/icon-m-clipboard"
onClicked: Clipboard.text = passwordmaker.generated_password;
}
}
Timer {
id: autoClearMasterPasswordTimer
property bool enabled: typeof passwordmaker.settings.clear_master_password_seconds !== 'undefined'
interval: passwordmaker.settings.clear_master_password_seconds*1000 || 10000000
running: false
onTriggered: if(enabled)
passwordmaker.master_password = "";
}
Timer {
id: autoClearGeneratedPasswordTimer
property bool enabled: typeof passwordmaker.settings.clear_generated_password_seconds !== 'undefined'
interval: passwordmaker.settings.clear_generated_password_seconds*1000 || 10000000
running: false
onTriggered: if(enabled){
passwordmaker.used_text = "";
passwordmaker.url = "";
}
}
}
NoticeOptional {
id: storeFailureNotice
text: qsTr("Saving settings failed.")
useNotificationFallback: true
}
Binding{
target: autoClearMasterPasswordTimer
property: "running"
value: false
when: !autoClearMasterPasswordTimer.enabled || isBackground === Qt.ApplicationActive
}
Binding{
target: autoClearGeneratedPasswordTimer
property: "running"
value: false
when: !autoClearGeneratedPasswordTimer.enabled || isBackground === Qt.ApplicationActive
}
}
readonly property int current_profile_index : passwordmaker.profiles.current_profile
onCurrent_profile_indexChanged: {mainFlickable.store_settings_with_error_message()}
}
|