ruby-pass-qt 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/lib/pass-qt/app/views/browsestoresdialog/ui.rb +77 -0
- data/lib/pass-qt/app/views/browsestoresdialog.rb +3 -69
- data/lib/pass-qt/app/{components → views/mainwindow/components}/passinfowidget/helpers.rb +1 -1
- data/lib/pass-qt/app/{components/passinfowidget.rb → views/mainwindow/components/passinfowidget/ui.rb} +21 -86
- data/lib/pass-qt/app/views/mainwindow/components/passinfowidget.rb +75 -0
- data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/helpers.rb +1 -1
- data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/treebuilder.rb +1 -1
- data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/treefilter.rb +1 -1
- data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/ui.rb +36 -0
- data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget.rb +3 -30
- data/lib/pass-qt/app/{components/passlistwidget.rb → views/mainwindow/components/passlistwidget/ui.rb} +13 -47
- data/lib/pass-qt/app/views/mainwindow/components/passlistwidget.rb +45 -0
- data/lib/pass-qt/app/views/mainwindow/ui.rb +39 -0
- data/lib/pass-qt/app/views/mainwindow.rb +5 -61
- data/lib/pass-qt/app/views/newonetimepassworddialog/ui.rb +90 -0
- data/lib/pass-qt/app/views/newonetimepassworddialog.rb +15 -93
- data/lib/pass-qt/app/views/newpassworddialog/ui.rb +111 -0
- data/lib/pass-qt/app/views/newpassworddialog.rb +18 -117
- data/lib/pass-qt/app.rb +2 -2
- data/lib/pass-qt/config/initializers/qt6.rb +1 -1
- data/lib/pass-qt/lib/{contrib/sighandler.rb → ctrlc/handler.rb} +6 -4
- data/lib/pass-qt/lib/ctrlc.rb +1 -0
- data/lib/pass-qt/lib/pass/{clients → backend}/gopass.rb +4 -4
- data/lib/pass-qt/lib/pass/{clients → backend}/pass.rb +6 -6
- data/lib/pass-qt/lib/pass/backend.rb +2 -0
- data/lib/pass-qt/lib/{contrib → pass}/process.rb +1 -1
- data/lib/pass-qt/lib/pass.rb +13 -11
- data/lib/pass-qt/lib.rb +1 -1
- data/lib/pass-qt/version.rb +1 -1
- metadata +22 -17
- data/lib/pass-qt/app/assets/README.md +0 -5
- data/lib/pass-qt/app/assets/app.svg +0 -1
- data/lib/pass-qt/lib/contrib.rb +0 -2
- data/lib/pass-qt/lib/pass/clients.rb +0 -2
- /data/lib/pass-qt/app/{components.rb → views/mainwindow/components.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0fb6805f75336a47b0d05fefce05aef65337a02726c03cae84d85587dc2ffe2c
|
|
4
|
+
data.tar.gz: dd7c0cad047c733a073bc301a8b57512da731888a62960d207015e8b1c2f0eab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b6a0044d9db31fb3cdd5c76ab9ac3c22266e371d6c2c9f18a58ed4de480740849c3cfcd4713cbd2344ac815b670a4d43c84db7e20f9ff8fb826488232c182ca4
|
|
7
|
+
data.tar.gz: '069c63341c0129c3c5b113572055d579873fe58f9e95b16e74f80d1deabf01ee7e4503f0404f58682187fb0f03d52ce9bab176826947c3678bd8f9e6e0614a88'
|
data/.rubocop.yml
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
class BrowseStoresDialog < RubyQt6::Bando::QDialog
|
|
2
|
+
private
|
|
3
|
+
|
|
4
|
+
def initialize_ui
|
|
5
|
+
initialize_toolbar
|
|
6
|
+
initialize_tablewidget
|
|
7
|
+
initialize_layout
|
|
8
|
+
|
|
9
|
+
set_attribute(Qt::WA_DeleteOnClose)
|
|
10
|
+
set_modal(true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize_toolbar
|
|
14
|
+
@toolbar = QWidget.new
|
|
15
|
+
|
|
16
|
+
btn = QPushButton.new(QIcon.from_theme(QIcon::ThemeIcon::ListAdd), "Add")
|
|
17
|
+
btn.clicked.connect(self, :_on_list_add_button_clicked)
|
|
18
|
+
|
|
19
|
+
qhboxlayout = QHBoxLayout.new(@toolbar)
|
|
20
|
+
qhboxlayout.add_widget(QLabel.new("Password Stores"))
|
|
21
|
+
qhboxlayout.add_stretch
|
|
22
|
+
qhboxlayout.add_widget(btn)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize_tablewidget
|
|
26
|
+
@tablewidget = QWidget.new
|
|
27
|
+
@tablewidget.set_object_name("browsestoresdialog_tablewidget")
|
|
28
|
+
@tablewidget.set_style_sheet("
|
|
29
|
+
#browsestoresdialog_tablewidget {
|
|
30
|
+
min-width: 600px;
|
|
31
|
+
background: white;
|
|
32
|
+
}
|
|
33
|
+
")
|
|
34
|
+
|
|
35
|
+
QVBoxLayout.new(@tablewidget)
|
|
36
|
+
PassQt.settings.GET_stores.each do |store|
|
|
37
|
+
update_tablewidget_addtableitem(store["fullpath"])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize_layout
|
|
42
|
+
mainlayout = QVBoxLayout.new(self)
|
|
43
|
+
mainlayout.add_stretch
|
|
44
|
+
mainlayout.add_widget(@toolbar)
|
|
45
|
+
mainlayout.add_widget(@tablewidget)
|
|
46
|
+
mainlayout.add_stretch
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def update_tablewidget_addtableitem(fullpath)
|
|
50
|
+
tableitem = QWidget.new
|
|
51
|
+
tableitemlayout = QHBoxLayout.new(tableitem)
|
|
52
|
+
|
|
53
|
+
label = QLabel.new(fullpath)
|
|
54
|
+
tableitemlayout.add_widget(label)
|
|
55
|
+
tableitemlayout.add_stretch
|
|
56
|
+
|
|
57
|
+
btn = QPushButton.new(QIcon.from_theme(QIcon::ThemeIcon::ListRemove), "Remove")
|
|
58
|
+
btn.clicked.connect(self, :_on_list_remove_button_clicked)
|
|
59
|
+
tableitemlayout.add_widget(btn)
|
|
60
|
+
|
|
61
|
+
@dataitems[fullpath] = DataItem.new(tableitem)
|
|
62
|
+
@tablewidget.layout.add_widget(tableitem)
|
|
63
|
+
update_settings_stores
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def update_tablewidget_removetableitem(tableitem)
|
|
67
|
+
@dataitems.delete_if { |_, item| item.tablewidgetitem == tableitem }
|
|
68
|
+
tableitem.delete_now
|
|
69
|
+
update_settings_stores
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def update_settings_stores
|
|
73
|
+
stores = @dataitems.map { |fullpath, _| {"fullpath" => fullpath} }
|
|
74
|
+
PassQt.settings.PUT_stores(stores)
|
|
75
|
+
stores_changed.emit
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative "browsestoresdialog/ui"
|
|
2
|
+
|
|
1
3
|
class BrowseStoresDialog < RubyQt6::Bando::QDialog
|
|
2
4
|
DataItem = Struct.new(:tablewidgetitem)
|
|
3
5
|
|
|
@@ -11,77 +13,11 @@ class BrowseStoresDialog < RubyQt6::Bando::QDialog
|
|
|
11
13
|
super
|
|
12
14
|
|
|
13
15
|
@dataitems = {}
|
|
14
|
-
|
|
15
|
-
initialize_toolbar
|
|
16
|
-
initialize_tablewidget
|
|
17
|
-
|
|
18
|
-
mainlayout = QVBoxLayout.new(self)
|
|
19
|
-
mainlayout.add_stretch
|
|
20
|
-
mainlayout.add_widget(@toolbar)
|
|
21
|
-
mainlayout.add_widget(@tablewidget)
|
|
22
|
-
mainlayout.add_stretch
|
|
23
|
-
|
|
24
|
-
set_attribute(Qt::WA_DeleteOnClose)
|
|
25
|
-
set_modal(true)
|
|
16
|
+
initialize_ui
|
|
26
17
|
end
|
|
27
18
|
|
|
28
19
|
private
|
|
29
20
|
|
|
30
|
-
def initialize_toolbar
|
|
31
|
-
@toolbar = QWidget.new
|
|
32
|
-
|
|
33
|
-
btn = QPushButton.new(QIcon.from_theme(QIcon::ThemeIcon::ListAdd), "Add")
|
|
34
|
-
btn.clicked.connect(self, :_on_list_add_button_clicked)
|
|
35
|
-
|
|
36
|
-
qhboxlayout = QHBoxLayout.new(@toolbar)
|
|
37
|
-
qhboxlayout.add_widget(QLabel.new("Password Stores"))
|
|
38
|
-
qhboxlayout.add_stretch
|
|
39
|
-
qhboxlayout.add_widget(btn)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def initialize_tablewidget
|
|
43
|
-
@tablewidget = QWidget.new
|
|
44
|
-
@tablewidget.set_object_name("browsestoresdialog_tablewidget")
|
|
45
|
-
@tablewidget.set_style_sheet("
|
|
46
|
-
#browsestoresdialog_tablewidget {
|
|
47
|
-
min-width: 600px;
|
|
48
|
-
background: white;
|
|
49
|
-
}
|
|
50
|
-
")
|
|
51
|
-
|
|
52
|
-
QVBoxLayout.new(@tablewidget)
|
|
53
|
-
PassQt.settings.GET_stores.each do |store|
|
|
54
|
-
update_tablewidget_addtableitem(store["fullpath"])
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def update_tablewidget_addtableitem(fullpath)
|
|
59
|
-
tableitem = QWidget.new
|
|
60
|
-
tableitemlayout = QHBoxLayout.new(tableitem)
|
|
61
|
-
|
|
62
|
-
label = QLabel.new(fullpath)
|
|
63
|
-
tableitemlayout.add_widget(label)
|
|
64
|
-
tableitemlayout.add_stretch
|
|
65
|
-
|
|
66
|
-
btn = QPushButton.new(QIcon.from_theme(QIcon::ThemeIcon::ListRemove), "Remove")
|
|
67
|
-
btn.clicked.connect(self, :_on_list_remove_button_clicked)
|
|
68
|
-
tableitemlayout.add_widget(btn)
|
|
69
|
-
|
|
70
|
-
@dataitems[fullpath] = DataItem.new(tableitem)
|
|
71
|
-
@tablewidget.layout.add_widget(tableitem)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def update_tablewidget_removetableitem(tableitem)
|
|
75
|
-
@dataitems.delete_if { |_, item| item.tablewidgetitem == tableitem }
|
|
76
|
-
tableitem.delete_now
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def update_settings_stores
|
|
80
|
-
stores = @dataitems.map { |fullpath, _| {"fullpath" => fullpath} }
|
|
81
|
-
PassQt.settings.PUT_stores(stores)
|
|
82
|
-
stores_changed.emit
|
|
83
|
-
end
|
|
84
|
-
|
|
85
21
|
def _on_list_add_button_clicked
|
|
86
22
|
dir = QFileDialog.get_existing_directory(self, "", QDir.home_path)
|
|
87
23
|
return if dir.empty?
|
|
@@ -99,11 +35,9 @@ class BrowseStoresDialog < RubyQt6::Bando::QDialog
|
|
|
99
35
|
end
|
|
100
36
|
|
|
101
37
|
update_tablewidget_addtableitem(dir)
|
|
102
|
-
update_settings_stores
|
|
103
38
|
end
|
|
104
39
|
|
|
105
40
|
def _on_list_remove_button_clicked
|
|
106
41
|
update_tablewidget_removetableitem(sender.parent)
|
|
107
|
-
update_settings_stores
|
|
108
42
|
end
|
|
109
43
|
end
|
|
@@ -1,69 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class PassInfoWidget < RubyQt6::Bando::QWidget
|
|
4
|
-
q_object do
|
|
5
|
-
slot "_on_copy_action_triggered()"
|
|
6
|
-
slot "_on_copy_action_triggered_otpcode()"
|
|
7
|
-
slot "_on_view_action_triggered()"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def initialize
|
|
11
|
-
super
|
|
12
|
-
|
|
13
|
-
@store = QString.new
|
|
14
|
-
@passname = QString.new
|
|
1
|
+
class MainWindowPassInfoWidget < RubyQt6::Bando::QWidget
|
|
2
|
+
private
|
|
15
3
|
|
|
4
|
+
def initialize_ui
|
|
16
5
|
initialize_form
|
|
17
6
|
initialize_otpform
|
|
18
7
|
initialize_folderform
|
|
19
8
|
initialize_infoframe
|
|
20
|
-
|
|
21
|
-
@stackedlayout = QStackedLayout.new
|
|
22
|
-
@stackedlayout.add_widget(@form)
|
|
23
|
-
@stackedlayout.add_widget(@otpform)
|
|
24
|
-
@stackedlayout.add_widget(@folderform)
|
|
25
|
-
@stackedlayout.add_widget(@infoframe)
|
|
26
|
-
|
|
27
|
-
mainlayout = QVBoxLayout.new(self)
|
|
28
|
-
mainlayout.add_spacing(76)
|
|
29
|
-
mainlayout.add_layout(@stackedlayout)
|
|
30
|
-
|
|
31
|
-
use_infoframe
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def use_passfilecard(store, passname)
|
|
35
|
-
@store = store
|
|
36
|
-
@passname = passname
|
|
37
|
-
use_infoframe
|
|
38
|
-
|
|
39
|
-
Pass.show(@store, @passname, on_success: ->(data) {
|
|
40
|
-
formdata = Helpers.parse_passfile(data)
|
|
41
|
-
if formdata["password"].start_with?("otpauth:")
|
|
42
|
-
use_otpform(formdata)
|
|
43
|
-
else
|
|
44
|
-
use_form(formdata)
|
|
45
|
-
end
|
|
46
|
-
}, on_failure: ->(data) {
|
|
47
|
-
errinfo = data["stderr"]
|
|
48
|
-
use_infoframe_err(errinfo)
|
|
49
|
-
})
|
|
9
|
+
initialize_layout
|
|
50
10
|
end
|
|
51
11
|
|
|
52
|
-
def use_passfoldercard(store, passname)
|
|
53
|
-
@store = store
|
|
54
|
-
@passname = passname
|
|
55
|
-
use_infoframe
|
|
56
|
-
use_folderform
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def use_infocard
|
|
60
|
-
@store = QString.new
|
|
61
|
-
@passname = QString.new
|
|
62
|
-
use_infoframe
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
private
|
|
66
|
-
|
|
67
12
|
def initialize_form
|
|
68
13
|
@passnameinput = initialize_form_inputfield
|
|
69
14
|
initialize_form_inputfield_copyaction(@passnameinput)
|
|
@@ -150,7 +95,19 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
|
|
|
150
95
|
infoframelayout.add_stretch
|
|
151
96
|
end
|
|
152
97
|
|
|
153
|
-
def
|
|
98
|
+
def initialize_layout
|
|
99
|
+
@stackedlayout = QStackedLayout.new
|
|
100
|
+
@stackedlayout.add_widget(@form)
|
|
101
|
+
@stackedlayout.add_widget(@otpform)
|
|
102
|
+
@stackedlayout.add_widget(@folderform)
|
|
103
|
+
@stackedlayout.add_widget(@infoframe)
|
|
104
|
+
|
|
105
|
+
mainlayout = QVBoxLayout.new(self)
|
|
106
|
+
mainlayout.add_spacing(76)
|
|
107
|
+
mainlayout.add_layout(@stackedlayout)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def activate_form(formdata)
|
|
154
111
|
@passnameinput.set_text(@passname)
|
|
155
112
|
@passwordinput.set_text(formdata["password"])
|
|
156
113
|
@passwordinput.set_echo_mode(QLineEdit::Password)
|
|
@@ -160,7 +117,7 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
|
|
|
160
117
|
@stackedlayout.set_current_widget(@form)
|
|
161
118
|
end
|
|
162
119
|
|
|
163
|
-
def
|
|
120
|
+
def activate_otpform(formdata)
|
|
164
121
|
@otppassnameinput.set_text(@passname)
|
|
165
122
|
@otppasswordinput.set_text(formdata["password"])
|
|
166
123
|
@otppasswordinput.set_cursor_position(0)
|
|
@@ -179,42 +136,20 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
|
|
|
179
136
|
}, on_failure: ->(_) {})
|
|
180
137
|
end
|
|
181
138
|
|
|
182
|
-
def
|
|
139
|
+
def activate_folderform
|
|
183
140
|
@folderpassnameinput.set_text(@passname)
|
|
184
141
|
@stackedlayout.set_current_widget(@folderform)
|
|
185
142
|
end
|
|
186
143
|
|
|
187
|
-
def
|
|
144
|
+
def activate_infoframe(info = "")
|
|
188
145
|
@infolabel.set_style_sheet("color: black;")
|
|
189
146
|
@infolabel.set_text(info)
|
|
190
147
|
@stackedlayout.set_current_widget(@infoframe)
|
|
191
148
|
end
|
|
192
149
|
|
|
193
|
-
def
|
|
150
|
+
def activate_infoframe_err(info)
|
|
194
151
|
@infolabel.set_style_sheet("color: red;")
|
|
195
152
|
@infolabel.set_text(info)
|
|
196
153
|
@stackedlayout.set_current_widget(@infoframe)
|
|
197
154
|
end
|
|
198
|
-
|
|
199
|
-
def _on_copy_action_triggered
|
|
200
|
-
input = sender.parent
|
|
201
|
-
QApplication.clipboard.set_text(input.text)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def _on_copy_action_triggered_otpcode
|
|
205
|
-
Pass.otp(@store, @passname, on_success: ->(data) {
|
|
206
|
-
otpcode = data["stdout"].rstrip
|
|
207
|
-
@otpcodeinput.set_text(otpcode)
|
|
208
|
-
QApplication.clipboard.set_text(otpcode)
|
|
209
|
-
}, on_failure: ->(_) {})
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def _on_view_action_triggered
|
|
213
|
-
input = sender.parent
|
|
214
|
-
case input.echo_mode
|
|
215
|
-
when QLineEdit::Normal then input.set_echo_mode(QLineEdit::Password)
|
|
216
|
-
when QLineEdit::Password then input.set_echo_mode(QLineEdit::Normal)
|
|
217
|
-
else raise "unreachable!"
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
155
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_relative "passinfowidget/helpers"
|
|
2
|
+
require_relative "passinfowidget/ui"
|
|
3
|
+
|
|
4
|
+
class MainWindowPassInfoWidget < RubyQt6::Bando::QWidget
|
|
5
|
+
q_object do
|
|
6
|
+
slot "activate_passfilecard(QString,QString)"
|
|
7
|
+
slot "activate_passfoldercard(QString,QString)"
|
|
8
|
+
slot "activate_infocard()"
|
|
9
|
+
slot "_on_copy_action_triggered()"
|
|
10
|
+
slot "_on_copy_action_triggered_otpcode()"
|
|
11
|
+
slot "_on_view_action_triggered()"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
initialize_ui
|
|
18
|
+
activate_infocard
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def activate_passfilecard(store, passname)
|
|
24
|
+
@store = store
|
|
25
|
+
@passname = passname
|
|
26
|
+
activate_infoframe
|
|
27
|
+
|
|
28
|
+
Pass.show(@store, @passname, on_success: ->(data) {
|
|
29
|
+
formdata = Helpers.parse_passfile(data)
|
|
30
|
+
if formdata["password"].start_with?("otpauth:")
|
|
31
|
+
activate_otpform(formdata)
|
|
32
|
+
else
|
|
33
|
+
activate_form(formdata)
|
|
34
|
+
end
|
|
35
|
+
}, on_failure: ->(data) {
|
|
36
|
+
errinfo = data["stderr"]
|
|
37
|
+
activate_infoframe_err(errinfo)
|
|
38
|
+
})
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def activate_passfoldercard(store, passname)
|
|
42
|
+
@store = store
|
|
43
|
+
@passname = passname
|
|
44
|
+
activate_infoframe
|
|
45
|
+
activate_folderform
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def activate_infocard
|
|
49
|
+
@store = QString.new
|
|
50
|
+
@passname = QString.new
|
|
51
|
+
activate_infoframe
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def _on_copy_action_triggered
|
|
55
|
+
input = sender.parent
|
|
56
|
+
QApplication.clipboard.set_text(input.text)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def _on_copy_action_triggered_otpcode
|
|
60
|
+
Pass.otp(@store, @passname, on_success: ->(data) {
|
|
61
|
+
otpcode = data["stdout"].rstrip
|
|
62
|
+
@otpcodeinput.set_text(otpcode)
|
|
63
|
+
QApplication.clipboard.set_text(otpcode)
|
|
64
|
+
}, on_failure: ->(_) {})
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def _on_view_action_triggered
|
|
68
|
+
input = sender.parent
|
|
69
|
+
case input.echo_mode
|
|
70
|
+
when QLineEdit::Normal then input.set_echo_mode(QLineEdit::Password)
|
|
71
|
+
when QLineEdit::Password then input.set_echo_mode(QLineEdit::Normal)
|
|
72
|
+
else raise "unreachable!"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class MainWindowPassListWidget < RubyQt6::Bando::QWidget
|
|
2
|
+
class TreeWidget < RubyQt6::Bando::QTreeWidget
|
|
3
|
+
private
|
|
4
|
+
|
|
5
|
+
def initialize_actions
|
|
6
|
+
@new_password_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New Password", :_on_new_password_action_triggered)
|
|
7
|
+
@new_otp_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New OTP", :_on_new_otp_action_triggered)
|
|
8
|
+
@delete_action = initialize_actions_act(QIcon::ThemeIcon::EditDelete, "Delete", :_on_delete_action_triggered)
|
|
9
|
+
@refresh_action = initialize_actions_act(QIcon::ThemeIcon::ViewRefresh, "Refresh", :_on_refresh_action_triggered)
|
|
10
|
+
@open_action = initialize_actions_act(QIcon::ThemeIcon::FolderVisiting, "Open Store With File Explorer", :_on_open_action_triggered)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize_actions_act(icon, text, slot)
|
|
14
|
+
action = QAction.new(QIcon.from_theme(icon), text, self)
|
|
15
|
+
action.triggered.connect(self, slot)
|
|
16
|
+
action
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize_context_menu
|
|
20
|
+
menu = QMenu.new("", self)
|
|
21
|
+
menu.set_attribute(Qt::WA_DeleteOnClose)
|
|
22
|
+
|
|
23
|
+
menu.add_action(@new_password_action)
|
|
24
|
+
menu.add_action(@new_otp_action)
|
|
25
|
+
menu.add_action(@delete_action)
|
|
26
|
+
menu.add_separator
|
|
27
|
+
menu.add_action(@refresh_action)
|
|
28
|
+
menu.add_action(@open_action)
|
|
29
|
+
|
|
30
|
+
enabled = !selected_items.empty?
|
|
31
|
+
@delete_action.set_enabled(enabled)
|
|
32
|
+
|
|
33
|
+
menu
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget.rb
RENAMED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
require_relative "treewidget/helpers"
|
|
2
2
|
require_relative "treewidget/treebuilder"
|
|
3
3
|
require_relative "treewidget/treefilter"
|
|
4
|
+
require_relative "treewidget/ui"
|
|
4
5
|
|
|
5
|
-
class
|
|
6
|
+
class MainWindowPassListWidget < RubyQt6::Bando::QWidget
|
|
6
7
|
class TreeWidget < RubyQt6::Bando::QTreeWidget
|
|
7
8
|
q_object do
|
|
8
9
|
signal "nil_selected(QString)"
|
|
@@ -23,25 +24,11 @@ class PassListWidget < RubyQt6::Bando::QWidget
|
|
|
23
24
|
@dataitems = {}
|
|
24
25
|
|
|
25
26
|
initialize_actions
|
|
26
|
-
|
|
27
27
|
current_item_changed.connect(self, :_on_current_item_changed)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def context_menu_event(evt)
|
|
31
|
-
menu =
|
|
32
|
-
menu.set_attribute(Qt::WA_DeleteOnClose)
|
|
33
|
-
|
|
34
|
-
menu.add_action(@new_password_action)
|
|
35
|
-
menu.add_action(@new_otp_action)
|
|
36
|
-
menu.add_action(@delete_action)
|
|
37
|
-
|
|
38
|
-
menu.add_separator
|
|
39
|
-
menu.add_action(@refresh_action)
|
|
40
|
-
menu.add_action(@open_action)
|
|
41
|
-
|
|
42
|
-
enabled = !selected_items.empty?
|
|
43
|
-
@delete_action.set_enabled(enabled)
|
|
44
|
-
|
|
31
|
+
menu = initialize_context_menu
|
|
45
32
|
menu.exec(evt.global_pos)
|
|
46
33
|
end
|
|
47
34
|
|
|
@@ -71,20 +58,6 @@ class PassListWidget < RubyQt6::Bando::QWidget
|
|
|
71
58
|
|
|
72
59
|
private
|
|
73
60
|
|
|
74
|
-
def initialize_actions
|
|
75
|
-
@new_password_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New Password", :_on_new_password_action_triggered)
|
|
76
|
-
@new_otp_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New OTP", :_on_new_otp_action_triggered)
|
|
77
|
-
@delete_action = initialize_actions_act(QIcon::ThemeIcon::EditDelete, "Delete", :_on_delete_action_triggered)
|
|
78
|
-
@refresh_action = initialize_actions_act(QIcon::ThemeIcon::ViewRefresh, "Refresh", :_on_refresh_action_triggered)
|
|
79
|
-
@open_action = initialize_actions_act(QIcon::ThemeIcon::FolderVisiting, "Open Store With File Explorer", :_on_open_action_triggered)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def initialize_actions_act(icon, text, slot)
|
|
83
|
-
action = QAction.new(QIcon.from_theme(icon), text, self)
|
|
84
|
-
action.triggered.connect(self, slot)
|
|
85
|
-
action
|
|
86
|
-
end
|
|
87
|
-
|
|
88
61
|
def _on_current_item_changed(curr, _prev)
|
|
89
62
|
if curr.nil?
|
|
90
63
|
nil_selected.emit(@store)
|
|
@@ -1,42 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class PassListWidget < RubyQt6::Bando::QWidget
|
|
4
|
-
q_object do
|
|
5
|
-
signal "store_changed(QString)"
|
|
6
|
-
signal "nil_selected(QString)"
|
|
7
|
-
signal "passfile_selected(QString,QString)"
|
|
8
|
-
signal "passfolder_selected(QString,QString)"
|
|
9
|
-
slot "_on_combobox_current_text_changed(QString)"
|
|
10
|
-
slot "_on_searchbar_text_changed(QString)"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
super
|
|
1
|
+
class MainWindowPassListWidget < RubyQt6::Bando::QWidget
|
|
2
|
+
private
|
|
15
3
|
|
|
4
|
+
def initialize_ui
|
|
16
5
|
initialize_combobox
|
|
17
6
|
initialize_searchbar
|
|
18
7
|
initialize_treewidget
|
|
8
|
+
initialize_layout
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
mainlayout.add_layout(@comboboxlayout)
|
|
22
|
-
mainlayout.add_widget(@searchbar)
|
|
23
|
-
mainlayout.add_widget(@treewidget)
|
|
24
|
-
|
|
25
|
-
update_combobox
|
|
10
|
+
update_combobox_using_settings_stores
|
|
26
11
|
end
|
|
27
12
|
|
|
28
|
-
def refresh
|
|
29
|
-
@combobox.block_signals(true).tap do |blocked|
|
|
30
|
-
@combobox.clear
|
|
31
|
-
ensure
|
|
32
|
-
@combobox.block_signals(blocked)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
update_combobox
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
13
|
def initialize_combobox
|
|
41
14
|
@combobox = QComboBox.new
|
|
42
15
|
@combobox.current_text_changed.connect(self, :_on_combobox_current_text_changed)
|
|
@@ -63,24 +36,17 @@ class PassListWidget < RubyQt6::Bando::QWidget
|
|
|
63
36
|
@treewidget.passfolder_selected.connect(self, :passfolder_selected)
|
|
64
37
|
end
|
|
65
38
|
|
|
66
|
-
def
|
|
39
|
+
def initialize_layout
|
|
40
|
+
mainlayout = QVBoxLayout.new(self)
|
|
41
|
+
mainlayout.add_layout(@comboboxlayout)
|
|
42
|
+
mainlayout.add_widget(@searchbar)
|
|
43
|
+
mainlayout.add_widget(@treewidget)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def update_combobox_using_settings_stores
|
|
67
47
|
PassQt.settings.GET_stores.each do |store|
|
|
68
48
|
fileinfo = QFileInfo.new(store["fullpath"])
|
|
69
49
|
@combobox.add_item(fileinfo.file_name, QVariant.new(fileinfo.absolute_file_path))
|
|
70
50
|
end
|
|
71
51
|
end
|
|
72
|
-
|
|
73
|
-
def _on_combobox_current_text_changed(_text)
|
|
74
|
-
store = @combobox.current_data.value
|
|
75
|
-
store_changed.emit(store)
|
|
76
|
-
|
|
77
|
-
@searchbar.clear
|
|
78
|
-
QTimer.single_shot(0, @searchbar, :set_focus)
|
|
79
|
-
|
|
80
|
-
@treewidget.refresh(store)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def _on_searchbar_text_changed(text)
|
|
84
|
-
@treewidget.update_passname_filter(text)
|
|
85
|
-
end
|
|
86
52
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require_relative "passlistwidget/treewidget"
|
|
2
|
+
require_relative "passlistwidget/ui"
|
|
3
|
+
|
|
4
|
+
class MainWindowPassListWidget < RubyQt6::Bando::QWidget
|
|
5
|
+
q_object do
|
|
6
|
+
signal "store_changed(QString)"
|
|
7
|
+
signal "nil_selected(QString)"
|
|
8
|
+
signal "passfile_selected(QString,QString)"
|
|
9
|
+
signal "passfolder_selected(QString,QString)"
|
|
10
|
+
slot "refresh()"
|
|
11
|
+
slot "_on_combobox_current_text_changed(QString)"
|
|
12
|
+
slot "_on_searchbar_text_changed(QString)"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
initialize_ui
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def refresh
|
|
24
|
+
@combobox.block_signals(true).tap do |blocked|
|
|
25
|
+
@combobox.clear
|
|
26
|
+
ensure
|
|
27
|
+
@combobox.block_signals(blocked)
|
|
28
|
+
end
|
|
29
|
+
update_combobox_using_settings_stores
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def _on_combobox_current_text_changed(_text)
|
|
33
|
+
store = @combobox.current_data.value
|
|
34
|
+
store_changed.emit(store)
|
|
35
|
+
|
|
36
|
+
@searchbar.clear
|
|
37
|
+
QTimer.single_shot(0, @searchbar, :set_focus)
|
|
38
|
+
|
|
39
|
+
@treewidget.refresh(store)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def _on_searchbar_text_changed(text)
|
|
43
|
+
@treewidget.update_passname_filter(text)
|
|
44
|
+
end
|
|
45
|
+
end
|