ruby-pass-qt 2.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 +3 -3
- data/lib/pass-qt/app/components/passinfowidget.rb +188 -190
- data/lib/pass-qt/app/components/passlistwidget/treewidget.rb +190 -192
- 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.rb +0 -1
- data/lib/pass-qt/version.rb +1 -1
- metadata +1 -1
|
@@ -1,243 +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
|
-
end
|
|
77
|
-
|
|
78
|
-
item = QTreeWidgetItem.new(diritem, QStringList.new << entry.complete_base_name << filepath)
|
|
79
|
-
item.set_icon(0, @fileiconprovider.icon(entry))
|
|
80
|
-
@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
|
|
81
75
|
end
|
|
82
|
-
end
|
|
83
76
|
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
86
81
|
end
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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)
|
|
95
92
|
end
|
|
93
|
+
return
|
|
94
|
+
end
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
re_options = QRegularExpression::UnanchoredWildcardConversion | QRegularExpression::NonPathWildcardConversion
|
|
97
|
+
re = QRegularExpression.from_wildcard(text, nil, re_options)
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
loop do
|
|
111
|
-
filepath_matched << filepath
|
|
112
|
-
filepath = QFileInfo.new(filepath).absolute_path
|
|
113
|
-
break unless @dataitems.key?(filepath)
|
|
114
|
-
end
|
|
105
|
+
if filepath_matched_1st.nil?
|
|
106
|
+
filepath_matched_1st = filepath if h_passfile?(filepath)
|
|
115
107
|
end
|
|
116
108
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
selected = filepath_matched_1st == filepath
|
|
122
|
-
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)
|
|
123
113
|
end
|
|
124
114
|
end
|
|
125
115
|
|
|
126
|
-
|
|
116
|
+
@dataitems.each do |filepath, item|
|
|
117
|
+
visible = filepath_matched.include?(filepath)
|
|
118
|
+
item.treewidgetitem.set_hidden(!visible)
|
|
127
119
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
@new_otp_action = initialize_actions_act(QIcon::ThemeIcon::DocumentNew, "New OTP", :_on_new_otp_action_triggered)
|
|
131
|
-
@delete_action = initialize_actions_act(QIcon::ThemeIcon::EditDelete, "Delete", :_on_delete_action_triggered)
|
|
132
|
-
@refresh_action = initialize_actions_act(QIcon::ThemeIcon::ViewRefresh, "Refresh", :_on_refresh_action_triggered)
|
|
133
|
-
@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)
|
|
134
122
|
end
|
|
123
|
+
end
|
|
135
124
|
|
|
136
|
-
|
|
137
|
-
action = QAction.new(QIcon.from_theme(icon), text, self)
|
|
138
|
-
action.triggered.connect(self, slot)
|
|
139
|
-
action
|
|
140
|
-
end
|
|
125
|
+
private
|
|
141
126
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
|
145
134
|
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
148
140
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
break
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
141
|
+
def initialize_fileiconprovider
|
|
142
|
+
@fileiconprovider = QFileIconProvider.new
|
|
143
|
+
end
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
|
162
152
|
end
|
|
163
153
|
end
|
|
154
|
+
end
|
|
164
155
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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!"
|
|
168
161
|
end
|
|
162
|
+
end
|
|
169
163
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
passfile_selected.emit(@store, dataitem.passname) :
|
|
175
|
-
passfolder_selected.emit(@store, dataitem.passname)
|
|
176
|
-
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
|
|
177
168
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
folder = ""
|
|
186
|
-
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
|
|
187
176
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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 = ""
|
|
192
185
|
end
|
|
193
186
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
folder = "" if folder == "."
|
|
200
|
-
else
|
|
201
|
-
folder = ""
|
|
202
|
-
end
|
|
187
|
+
dialog = NewPasswordDialog.new(@store, folder, on_success: ->(passname) {
|
|
188
|
+
reinitialize(selected_passname: passname)
|
|
189
|
+
})
|
|
190
|
+
dialog.show
|
|
191
|
+
end
|
|
203
192
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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 = ""
|
|
208
201
|
end
|
|
209
202
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
203
|
+
dialog = NewOneTimePasswordDialog.new(@store, folder, on_success: ->(passname) {
|
|
204
|
+
reinitialize(selected_passname: passname)
|
|
205
|
+
})
|
|
206
|
+
dialog.show
|
|
207
|
+
end
|
|
214
208
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
209
|
+
def _on_delete_action_triggered
|
|
210
|
+
item = selected_items[0]
|
|
211
|
+
filepath = item.data(1, Qt::DisplayRole).value
|
|
212
|
+
dataitem = @dataitems[filepath]
|
|
218
213
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
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
|
|
223
217
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
dataitem = @dataitems[filepath]
|
|
229
|
-
passname = dataitem.passname
|
|
230
|
-
else
|
|
231
|
-
passname = ""
|
|
232
|
-
end
|
|
218
|
+
file = QFile.new(filepath)
|
|
219
|
+
file.move_to_trash
|
|
220
|
+
reinitialize
|
|
221
|
+
end
|
|
233
222
|
|
|
234
|
-
|
|
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 = ""
|
|
235
231
|
end
|
|
236
232
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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)
|
|
241
239
|
end
|
|
242
240
|
end
|
|
243
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
|