ruby-pass-qt 2.0.6 → 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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/lib/pass-qt/app/views/browsestoresdialog/ui.rb +77 -0
  4. data/lib/pass-qt/app/views/browsestoresdialog.rb +3 -69
  5. data/lib/pass-qt/app/{components → views/mainwindow/components}/passinfowidget/helpers.rb +1 -1
  6. data/lib/pass-qt/app/{components/passinfowidget.rb → views/mainwindow/components/passinfowidget/ui.rb} +30 -87
  7. data/lib/pass-qt/app/views/mainwindow/components/passinfowidget.rb +75 -0
  8. data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/helpers.rb +1 -1
  9. data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/treebuilder.rb +1 -1
  10. data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget/treefilter.rb +1 -1
  11. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/ui.rb +36 -0
  12. data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget.rb +3 -30
  13. data/lib/pass-qt/app/{components/passlistwidget.rb → views/mainwindow/components/passlistwidget/ui.rb} +13 -47
  14. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget.rb +45 -0
  15. data/lib/pass-qt/app/views/mainwindow/ui.rb +39 -0
  16. data/lib/pass-qt/app/views/mainwindow.rb +5 -61
  17. data/lib/pass-qt/app/views/newonetimepassworddialog/ui.rb +90 -0
  18. data/lib/pass-qt/app/views/newonetimepassworddialog.rb +15 -93
  19. data/lib/pass-qt/app/views/newpassworddialog/ui.rb +111 -0
  20. data/lib/pass-qt/app/views/newpassworddialog.rb +18 -117
  21. data/lib/pass-qt/app.rb +2 -2
  22. data/lib/pass-qt/config/initializers/qt6.rb +1 -1
  23. data/lib/pass-qt/lib/{contrib/sighandler.rb → ctrlc/handler.rb} +6 -4
  24. data/lib/pass-qt/lib/ctrlc.rb +1 -0
  25. data/lib/pass-qt/lib/pass/{clients → backend}/gopass.rb +4 -4
  26. data/lib/pass-qt/lib/pass/{clients → backend}/pass.rb +6 -6
  27. data/lib/pass-qt/lib/pass/backend.rb +2 -0
  28. data/lib/pass-qt/lib/{contrib → pass}/process.rb +1 -1
  29. data/lib/pass-qt/lib/pass.rb +13 -11
  30. data/lib/pass-qt/lib.rb +1 -1
  31. data/lib/pass-qt/version.rb +1 -1
  32. metadata +22 -17
  33. data/lib/pass-qt/app/assets/README.md +0 -5
  34. data/lib/pass-qt/app/assets/app.svg +0 -1
  35. data/lib/pass-qt/lib/contrib.rb +0 -2
  36. data/lib/pass-qt/lib/pass/clients.rb +0 -2
  37. /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: ccf6b7039c5cb6f8031411669023603b89b141ef7b70a1c43841823edaa43ba9
4
- data.tar.gz: acca47730f2fcaeec6a3ab3dbde623a6f14aa6c23b6a370b7b753fa581e9e03a
3
+ metadata.gz: 0fb6805f75336a47b0d05fefce05aef65337a02726c03cae84d85587dc2ffe2c
4
+ data.tar.gz: dd7c0cad047c733a073bc301a8b57512da731888a62960d207015e8b1c2f0eab
5
5
  SHA512:
6
- metadata.gz: 218b95a3dc22dc62348daaf00d1be28e9d0b3230c2eb894518c60f188b6e7caa861275088fb6876929d299aa42d323c75f5b14a4d31d4431e8db2426afac2dfc
7
- data.tar.gz: cfa0427bf5310897557e10dd72f4f558979abf96157d24b0c38c94eae2d716d4d4569d75a2f4795bcf89ea6b6b2b0c0ce61e413ee31ed966d31a80703fc5a8d5
6
+ metadata.gz: b6a0044d9db31fb3cdd5c76ab9ac3c22266e371d6c2c9f18a58ed4de480740849c3cfcd4713cbd2344ac815b670a4d43c84db7e20f9ff8fb826488232c182ca4
7
+ data.tar.gz: '069c63341c0129c3c5b113572055d579873fe58f9e95b16e74f80d1deabf01ee7e4503f0404f58682187fb0f03d52ce9bab176826947c3678bd8f9e6e0614a88'
data/.rubocop.yml CHANGED
@@ -8,3 +8,7 @@ AllCops:
8
8
  Exclude:
9
9
  - "bin/**/*"
10
10
  - "tmp/**/*"
11
+
12
+ Style/GlobalVars:
13
+ AllowedVariables:
14
+ - '$qApp'
@@ -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,4 +1,4 @@
1
- class PassInfoWidget < RubyQt6::Bando::QWidget
1
+ class MainWindowPassInfoWidget < RubyQt6::Bando::QWidget
2
2
  module Helpers
3
3
  def self.parse_passfile(data)
4
4
  lines = data["stdout"].lines
@@ -1,69 +1,14 @@
1
- require_relative "passinfowidget/helpers"
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)
@@ -94,6 +39,9 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
94
39
  initialize_form_inputfield_copyaction(@otppasswordinput)
95
40
  initialize_form_inputfield_viewaction(@otppasswordinput)
96
41
 
42
+ @otpaccountinput = initialize_form_inputfield
43
+ initialize_form_inputfield_copyaction(@otpaccountinput)
44
+
97
45
  @otpcodeinput = initialize_form_inputfield
98
46
  action = @otpcodeinput.add_action(QIcon.from_theme(QIcon::ThemeIcon::EditCopy), QLineEdit::LeadingPosition)
99
47
  action.triggered.connect(self, :_on_copy_action_triggered_otpcode)
@@ -102,7 +50,8 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
102
50
  otpformlayout = QFormLayout.new(@otpform)
103
51
  otpformlayout.add_row(initialize_form_label("File"), @otppassnameinput)
104
52
  otpformlayout.add_row(initialize_form_label("OTP URI"), @otppasswordinput)
105
- otpformlayout.add_row(initialize_form_label("OTP Code"), @otpcodeinput)
53
+ otpformlayout.add_row(initialize_form_label("Account"), @otpaccountinput)
54
+ otpformlayout.add_row(initialize_form_label("Code"), @otpcodeinput)
106
55
  end
107
56
 
108
57
  def initialize_folderform
@@ -146,7 +95,19 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
146
95
  infoframelayout.add_stretch
147
96
  end
148
97
 
149
- def use_form(formdata)
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)
150
111
  @passnameinput.set_text(@passname)
151
112
  @passwordinput.set_text(formdata["password"])
152
113
  @passwordinput.set_echo_mode(QLineEdit::Password)
@@ -156,12 +117,16 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
156
117
  @stackedlayout.set_current_widget(@form)
157
118
  end
158
119
 
159
- def use_otpform(formdata)
120
+ def activate_otpform(formdata)
160
121
  @otppassnameinput.set_text(@passname)
161
122
  @otppasswordinput.set_text(formdata["password"])
162
123
  @otppasswordinput.set_cursor_position(0)
163
124
  @otppasswordinput.set_echo_mode(QLineEdit::Password)
164
125
 
126
+ label = QUrl.new(formdata["password"]).path.to_s[1..]
127
+ account = label.split(":")[-1]
128
+ @otpaccountinput.set_text(account)
129
+
165
130
  @otpcodeinput.set_text("")
166
131
  @stackedlayout.set_current_widget(@otpform)
167
132
 
@@ -171,42 +136,20 @@ class PassInfoWidget < RubyQt6::Bando::QWidget
171
136
  }, on_failure: ->(_) {})
172
137
  end
173
138
 
174
- def use_folderform
139
+ def activate_folderform
175
140
  @folderpassnameinput.set_text(@passname)
176
141
  @stackedlayout.set_current_widget(@folderform)
177
142
  end
178
143
 
179
- def use_infoframe(info = "")
144
+ def activate_infoframe(info = "")
180
145
  @infolabel.set_style_sheet("color: black;")
181
146
  @infolabel.set_text(info)
182
147
  @stackedlayout.set_current_widget(@infoframe)
183
148
  end
184
149
 
185
- def use_infoframe_err(info)
150
+ def activate_infoframe_err(info)
186
151
  @infolabel.set_style_sheet("color: red;")
187
152
  @infolabel.set_text(info)
188
153
  @stackedlayout.set_current_widget(@infoframe)
189
154
  end
190
-
191
- def _on_copy_action_triggered
192
- input = sender.parent
193
- QApplication.clipboard.set_text(input.text)
194
- end
195
-
196
- def _on_copy_action_triggered_otpcode
197
- Pass.otp(@store, @passname, on_success: ->(data) {
198
- otpcode = data["stdout"].rstrip
199
- @otpcodeinput.set_text(otpcode)
200
- QApplication.clipboard.set_text(otpcode)
201
- }, on_failure: ->(_) {})
202
- end
203
-
204
- def _on_view_action_triggered
205
- input = sender.parent
206
- case input.echo_mode
207
- when QLineEdit::Normal then input.set_echo_mode(QLineEdit::Password)
208
- when QLineEdit::Password then input.set_echo_mode(QLineEdit::Normal)
209
- else raise "unreachable!"
210
- end
211
- end
212
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
@@ -1,4 +1,4 @@
1
- class PassListWidget < RubyQt6::Bando::QWidget
1
+ class MainWindowPassListWidget < RubyQt6::Bando::QWidget
2
2
  class TreeWidget < RubyQt6::Bando::QTreeWidget
3
3
  module Helpers
4
4
  def self.passfile?(fileinfo)
@@ -1,4 +1,4 @@
1
- class PassListWidget < RubyQt6::Bando::QWidget
1
+ class MainWindowPassListWidget < RubyQt6::Bando::QWidget
2
2
  class TreeWidget < RubyQt6::Bando::QTreeWidget
3
3
  DataItem = Struct.new(:passname, :treewidgetitem)
4
4
 
@@ -1,4 +1,4 @@
1
- class PassListWidget < RubyQt6::Bando::QWidget
1
+ class MainWindowPassListWidget < RubyQt6::Bando::QWidget
2
2
  class TreeWidget < RubyQt6::Bando::QTreeWidget
3
3
  class TreeFilter
4
4
  def perform(treewidget, dataitems, text)
@@ -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
@@ -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 PassListWidget < RubyQt6::Bando::QWidget
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 = QMenu.new("", self)
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
- require_relative "passlistwidget/treewidget"
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
- mainlayout = QVBoxLayout.new(self)
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 update_combobox
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