ruby-pass-qt 1.0.0 → 2.0.1
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/README.md +7 -6
- data/lib/pass-qt/app/components/passinfowidget.rb +188 -190
- data/lib/pass-qt/app/components/passlistwidget/treewidget.rb +190 -189
- data/lib/pass-qt/app/components/passlistwidget.rb +68 -70
- data/lib/pass-qt/app/views/browsestoresdialog.rb +85 -87
- data/lib/pass-qt/app/views/mainwindow.rb +76 -78
- data/lib/pass-qt/app/views/newonetimepassworddialog.rb +108 -110
- data/lib/pass-qt/app/views/newpassworddialog.rb +141 -143
- data/lib/pass-qt/config/initializers/qt6.rb +1 -0
- data/lib/pass-qt/config.rb +0 -1
- data/lib/pass-qt/lib/pass/clients/gopass.rb +21 -0
- data/lib/pass-qt/lib/pass/clients/pass.rb +40 -0
- data/lib/pass-qt/lib/pass/clients.rb +2 -0
- data/lib/pass-qt/lib/pass.rb +21 -16
- data/lib/pass-qt/version.rb +1 -1
- metadata +6 -3
|
@@ -1,240 +1,241 @@
|
|
|
1
|
-
|
|
2
|
-
class
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
end
|
|
1
|
+
class PassListWidget < RubyQt6::Bando::QWidget
|
|
2
|
+
class TreeWidget < RubyQt6::Bando::QTreeWidget
|
|
3
|
+
DataItem = Struct.new(:passname, :treewidgetitem)
|
|
4
|
+
|
|
5
|
+
q_object do
|
|
6
|
+
signal "store_changed(QString)"
|
|
7
|
+
signal "passfile_selected(QString,QString)"
|
|
8
|
+
signal "passfolder_selected(QString,QString)"
|
|
9
|
+
slot "_on_item_clicked(QTreeWidgetItem*,int)"
|
|
10
|
+
slot "_on_new_password_action_triggered()"
|
|
11
|
+
slot "_on_new_otp_action_triggered()"
|
|
12
|
+
slot "_on_delete_action_triggered()"
|
|
13
|
+
slot "_on_refresh_action_triggered()"
|
|
14
|
+
slot "_on_open_action_triggered()"
|
|
15
|
+
end
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
def initialize
|
|
18
|
+
super
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
@store = QString.new
|
|
21
|
+
@dataitems = {}
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
initialize_actions
|
|
24
|
+
initialize_fileiconprovider
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
item_clicked.connect(self, :_on_item_clicked)
|
|
27
|
+
end
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
def context_menu_event(evt)
|
|
30
|
+
menu = QMenu.new("", self)
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
menu.add_action(@new_password_action)
|
|
33
|
+
menu.add_action(@new_otp_action)
|
|
34
|
+
menu.add_action(@delete_action)
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
menu.add_separator
|
|
37
|
+
menu.add_action(@refresh_action)
|
|
38
|
+
menu.add_action(@open_action)
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
enabled = !selected_items.empty?
|
|
41
|
+
@delete_action.set_enabled(enabled)
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
menu.exec(evt.global_pos)
|
|
44
|
+
end
|
|
46
45
|
|
|
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
|
-
item.set_icon(0, @fileiconprovider.icon(entry))
|
|
77
|
-
@dataitems[filepath] = DataItem.new(passname, item)
|
|
46
|
+
def reinitialize_store(store)
|
|
47
|
+
clear
|
|
48
|
+
|
|
49
|
+
@store = store
|
|
50
|
+
@dataitems = {}
|
|
51
|
+
|
|
52
|
+
store_root_path = QDir.new(@store)
|
|
53
|
+
dirs = [store]
|
|
54
|
+
until dirs.empty?
|
|
55
|
+
dir = dirs.shift
|
|
56
|
+
diritem = @dataitems[dir]&.treewidgetitem || invisible_root_item
|
|
57
|
+
|
|
58
|
+
entry_list = QDir.new(dir).entry_info_list(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)
|
|
59
|
+
entry_list.each do |entry|
|
|
60
|
+
next if entry.hidden?
|
|
61
|
+
next if entry.file_name.starts_with(".")
|
|
62
|
+
|
|
63
|
+
filepath = entry.absolute_file_path
|
|
64
|
+
next if @dataitems.key?(filepath)
|
|
65
|
+
|
|
66
|
+
if entry.dir?
|
|
67
|
+
dirs << filepath
|
|
68
|
+
passname = store_root_path.relative_file_path(filepath)
|
|
69
|
+
elsif entry.file?
|
|
70
|
+
next unless h_passfile?(entry)
|
|
71
|
+
passname = store_root_path.relative_file_path(filepath)
|
|
72
|
+
passname = passname[0, passname.size - entry.suffix.size - 1]
|
|
73
|
+
else
|
|
74
|
+
next
|
|
78
75
|
end
|
|
79
|
-
end
|
|
80
76
|
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
item = QTreeWidgetItem.new(diritem, QStringList.new << entry.complete_base_name << filepath)
|
|
78
|
+
item.set_icon(0, @fileiconprovider.icon(entry))
|
|
79
|
+
@dataitems[filepath] = DataItem.new(passname, item)
|
|
80
|
+
end
|
|
83
81
|
end
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
expand_all
|
|
84
|
+
store_changed.emit(@store)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def update_passname_filter(text)
|
|
88
|
+
if text.empty?
|
|
89
|
+
@dataitems.each do |_, item|
|
|
90
|
+
item.treewidgetitem.set_hidden(false)
|
|
91
|
+
item.treewidgetitem.set_selected(false)
|
|
92
92
|
end
|
|
93
|
+
return
|
|
94
|
+
end
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
re_options = QRegularExpression::UnanchoredWildcardConversion | QRegularExpression::NonPathWildcardConversion
|
|
97
|
+
re = QRegularExpression.from_wildcard(text, nil, re_options)
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
filepath_matched = Set.new
|
|
100
|
+
filepath_matched_1st = nil
|
|
101
|
+
@dataitems.each do |filepath, item|
|
|
102
|
+
has_match = re.match(item.passname).has_match
|
|
103
|
+
next unless has_match
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
loop do
|
|
108
|
-
filepath_matched << filepath
|
|
109
|
-
filepath = QFileInfo.new(filepath).absolute_path
|
|
110
|
-
break unless @dataitems.key?(filepath)
|
|
111
|
-
end
|
|
105
|
+
if filepath_matched_1st.nil?
|
|
106
|
+
filepath_matched_1st = filepath if h_passfile?(filepath)
|
|
112
107
|
end
|
|
113
108
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
selected = filepath_matched_1st == filepath
|
|
119
|
-
item.treewidgetitem.set_selected(selected)
|
|
109
|
+
loop do
|
|
110
|
+
filepath_matched << filepath
|
|
111
|
+
filepath = QFileInfo.new(filepath).absolute_path
|
|
112
|
+
break unless @dataitems.key?(filepath)
|
|
120
113
|
end
|
|
121
114
|
end
|
|
122
115
|
|
|
123
|
-
|
|
116
|
+
@dataitems.each do |filepath, item|
|
|
117
|
+
visible = filepath_matched.include?(filepath)
|
|
118
|
+
item.treewidgetitem.set_hidden(!visible)
|
|
124
119
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
@new_otp_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New OTP", :_on_new_otp_action_triggered)
|
|
128
|
-
@delete_action = initialize_actions_act(QIcon::ThemeIcon::EditDelete, "Delete", :_on_delete_action_triggered)
|
|
129
|
-
@refresh_action = initialize_actions_act(QIcon::ThemeIcon::ViewRefresh, "Refresh", :_on_refresh_action_triggered)
|
|
130
|
-
@open_action = initialize_actions_act(QIcon::ThemeIcon::FolderVisiting, "Open Store With File Explorer", :_on_open_action_triggered)
|
|
120
|
+
selected = filepath_matched_1st == filepath
|
|
121
|
+
item.treewidgetitem.set_selected(selected)
|
|
131
122
|
end
|
|
123
|
+
end
|
|
132
124
|
|
|
133
|
-
|
|
134
|
-
action = QAction.new(QIcon.from_theme(icon), text, self)
|
|
135
|
-
action.triggered.connect(self, slot)
|
|
136
|
-
action
|
|
137
|
-
end
|
|
125
|
+
private
|
|
138
126
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
127
|
+
def initialize_actions
|
|
128
|
+
@new_password_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New Password", :_on_new_password_action_triggered)
|
|
129
|
+
@new_otp_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New OTP", :_on_new_otp_action_triggered)
|
|
130
|
+
@delete_action = initialize_actions_act(QIcon::ThemeIcon::EditDelete, "Delete", :_on_delete_action_triggered)
|
|
131
|
+
@refresh_action = initialize_actions_act(QIcon::ThemeIcon::ViewRefresh, "Refresh", :_on_refresh_action_triggered)
|
|
132
|
+
@open_action = initialize_actions_act(QIcon::ThemeIcon::FolderVisiting, "Open Store With File Explorer", :_on_open_action_triggered)
|
|
133
|
+
end
|
|
142
134
|
|
|
143
|
-
|
|
144
|
-
|
|
135
|
+
def initialize_actions_act(icon, text, slot)
|
|
136
|
+
action = QAction.new(QIcon.from_theme(icon), text, self)
|
|
137
|
+
action.triggered.connect(self, slot)
|
|
138
|
+
action
|
|
139
|
+
end
|
|
145
140
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
break
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
end
|
|
141
|
+
def initialize_fileiconprovider
|
|
142
|
+
@fileiconprovider = QFileIconProvider.new
|
|
143
|
+
end
|
|
153
144
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
def reinitialize(selected_passname: "")
|
|
146
|
+
reinitialize_store(@store)
|
|
147
|
+
|
|
148
|
+
@dataitems.each do |_, item|
|
|
149
|
+
if item.passname == selected_passname
|
|
150
|
+
item.treewidgetitem.set_selected(true)
|
|
151
|
+
break
|
|
159
152
|
end
|
|
160
153
|
end
|
|
154
|
+
end
|
|
161
155
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
156
|
+
def h_passfile?(fileinfo)
|
|
157
|
+
case fileinfo
|
|
158
|
+
when QFileInfo then fileinfo.suffix.downcase == "gpg"
|
|
159
|
+
when QString then fileinfo.ends_with(".gpg", Qt::CaseInsensitive)
|
|
160
|
+
else raise "unreachable!"
|
|
165
161
|
end
|
|
162
|
+
end
|
|
166
163
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
passfile_selected.emit(@store, dataitem.passname) :
|
|
172
|
-
passfolder_selected.emit(@store, dataitem.passname)
|
|
173
|
-
end
|
|
164
|
+
def h_folderpath(fileinfo)
|
|
165
|
+
folder = fileinfo.dir? ? fileinfo.absolute_file_path : fileinfo.absolute_path
|
|
166
|
+
QDir.new(@store).relative_file_path(folder)
|
|
167
|
+
end
|
|
174
168
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
folder = ""
|
|
183
|
-
end
|
|
169
|
+
def _on_item_clicked(item, _column)
|
|
170
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
171
|
+
dataitem = @dataitems[filepath]
|
|
172
|
+
h_passfile?(filepath) ?
|
|
173
|
+
passfile_selected.emit(@store, dataitem.passname) :
|
|
174
|
+
passfolder_selected.emit(@store, dataitem.passname)
|
|
175
|
+
end
|
|
184
176
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
177
|
+
def _on_new_password_action_triggered
|
|
178
|
+
item = selected_items[0]
|
|
179
|
+
if item
|
|
180
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
181
|
+
folder = h_folderpath(QFileInfo.new(filepath))
|
|
182
|
+
folder = "" if folder == "."
|
|
183
|
+
else
|
|
184
|
+
folder = ""
|
|
189
185
|
end
|
|
190
186
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
folder = "" if folder == "."
|
|
197
|
-
else
|
|
198
|
-
folder = ""
|
|
199
|
-
end
|
|
187
|
+
dialog = NewPasswordDialog.new(@store, folder, on_success: ->(passname) {
|
|
188
|
+
reinitialize(selected_passname: passname)
|
|
189
|
+
})
|
|
190
|
+
dialog.show
|
|
191
|
+
end
|
|
200
192
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
193
|
+
def _on_new_otp_action_triggered
|
|
194
|
+
item = selected_items[0]
|
|
195
|
+
if item
|
|
196
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
197
|
+
folder = h_folderpath(QFileInfo.new(filepath))
|
|
198
|
+
folder = "" if folder == "."
|
|
199
|
+
else
|
|
200
|
+
folder = ""
|
|
205
201
|
end
|
|
206
202
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
dialog = NewOneTimePasswordDialog.new(@store, folder, on_success: ->(passname) {
|
|
204
|
+
reinitialize(selected_passname: passname)
|
|
205
|
+
})
|
|
206
|
+
dialog.show
|
|
207
|
+
end
|
|
211
208
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
209
|
+
def _on_delete_action_triggered
|
|
210
|
+
item = selected_items[0]
|
|
211
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
212
|
+
dataitem = @dataitems[filepath]
|
|
215
213
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
end
|
|
214
|
+
message = "<p>Do you really want to delete this item?</p>#{dataitem.passname}"
|
|
215
|
+
reply = QMessageBox.question(self, "", message)
|
|
216
|
+
return if reply == QMessageBox::No
|
|
220
217
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
dataitem = @dataitems[filepath]
|
|
226
|
-
passname = dataitem.passname
|
|
227
|
-
else
|
|
228
|
-
passname = ""
|
|
229
|
-
end
|
|
218
|
+
file = QFile.new(filepath)
|
|
219
|
+
file.move_to_trash
|
|
220
|
+
reinitialize
|
|
221
|
+
end
|
|
230
222
|
|
|
231
|
-
|
|
223
|
+
def _on_refresh_action_triggered
|
|
224
|
+
item = selected_items[0]
|
|
225
|
+
if item
|
|
226
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
227
|
+
dataitem = @dataitems[filepath]
|
|
228
|
+
passname = dataitem.passname
|
|
229
|
+
else
|
|
230
|
+
passname = ""
|
|
232
231
|
end
|
|
233
232
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
reinitialize(selected_passname: passname)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def _on_open_action_triggered
|
|
237
|
+
url = QUrl.from_local_file(@store)
|
|
238
|
+
QDesktopServices.open_url(url)
|
|
238
239
|
end
|
|
239
240
|
end
|
|
240
241
|
end
|
|
@@ -1,91 +1,89 @@
|
|
|
1
1
|
require_relative "passlistwidget/treewidget"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
3
|
+
class PassListWidget < RubyQt6::Bando::QWidget
|
|
4
|
+
q_object do
|
|
5
|
+
signal "store_changed(QString)"
|
|
6
|
+
signal "passfile_selected(QString,QString)"
|
|
7
|
+
signal "passfolder_selected(QString,QString)"
|
|
8
|
+
slot "_on_combobox_current_text_changed(QString)"
|
|
9
|
+
slot "_on_searchbar_text_changed(QString)"
|
|
10
|
+
slot "_on_treewidget_store_changed(QString)"
|
|
11
|
+
end
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
def initialize
|
|
14
|
+
super
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
initialize_combobox
|
|
17
|
+
initialize_searchbar
|
|
18
|
+
initialize_treewidget
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
mainlayout = QVBoxLayout.new(self)
|
|
21
|
+
mainlayout.add_layout(@comboboxlayout)
|
|
22
|
+
mainlayout.add_widget(@searchbar)
|
|
23
|
+
mainlayout.add_widget(@treewidget)
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def reinitialize_stores
|
|
30
|
-
@combobox.block_signals(true).tap do |blocked|
|
|
31
|
-
@combobox.clear
|
|
32
|
-
ensure
|
|
33
|
-
@combobox.block_signals(blocked)
|
|
34
|
-
end
|
|
25
|
+
update_combobox
|
|
26
|
+
end
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
def reinitialize_stores
|
|
29
|
+
@combobox.block_signals(true).tap do |blocked|
|
|
30
|
+
@combobox.clear
|
|
31
|
+
ensure
|
|
32
|
+
@combobox.block_signals(blocked)
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
update_combobox
|
|
36
|
+
end
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
@combobox = QComboBox.new
|
|
43
|
-
@combobox.current_text_changed.connect(self, :_on_combobox_current_text_changed)
|
|
38
|
+
private
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@comboboxlayout.set_stretch(0, 2)
|
|
49
|
-
@comboboxlayout.set_stretch(1, 3)
|
|
50
|
-
end
|
|
40
|
+
def initialize_combobox
|
|
41
|
+
@combobox = QComboBox.new
|
|
42
|
+
@combobox.current_text_changed.connect(self, :_on_combobox_current_text_changed)
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
@comboboxlayout = QHBoxLayout.new
|
|
45
|
+
@comboboxlayout.add_widget(QLabel.new("Current Store"))
|
|
46
|
+
@comboboxlayout.add_widget(@combobox)
|
|
47
|
+
@comboboxlayout.set_stretch(0, 2)
|
|
48
|
+
@comboboxlayout.set_stretch(1, 3)
|
|
49
|
+
end
|
|
58
50
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
51
|
+
def initialize_searchbar
|
|
52
|
+
@searchbar = QLineEdit.new
|
|
53
|
+
@searchbar.set_clear_button_enabled(true)
|
|
54
|
+
@searchbar.set_placeholder_text("List passwords that match passname...")
|
|
55
|
+
@searchbar.text_changed.connect(self, :_on_searchbar_text_changed)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def initialize_treewidget
|
|
59
|
+
@treewidget = TreeWidget.new
|
|
60
|
+
@treewidget.set_header_hidden(true)
|
|
61
|
+
@treewidget.store_changed.connect(self, :_on_treewidget_store_changed)
|
|
62
|
+
@treewidget.passfile_selected.connect(self, :passfile_selected)
|
|
63
|
+
@treewidget.passfolder_selected.connect(self, :passfolder_selected)
|
|
64
|
+
end
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
end
|
|
66
|
+
def update_combobox
|
|
67
|
+
PassQt.settings.GET_stores.each do |store|
|
|
68
|
+
fileinfo = QFileInfo.new(store["fullpath"])
|
|
69
|
+
@combobox.add_item(fileinfo.file_name, QVariant.new(fileinfo.absolute_file_path))
|
|
72
70
|
end
|
|
71
|
+
end
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
def _on_combobox_current_text_changed(_text)
|
|
74
|
+
store = @combobox.current_data.value
|
|
75
|
+
@treewidget.reinitialize_store(store)
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
@searchbar.clear
|
|
78
|
+
QTimer.single_shot(0, @searchbar, :set_focus)
|
|
79
|
+
end
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
def _on_searchbar_text_changed(text)
|
|
82
|
+
@treewidget.update_passname_filter(text)
|
|
83
|
+
end
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
end
|
|
85
|
+
def _on_treewidget_store_changed(store)
|
|
86
|
+
@searchbar.clear
|
|
87
|
+
store_changed.emit(store)
|
|
90
88
|
end
|
|
91
89
|
end
|