ruby-pass-qt 2.0.7 → 2.1.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.
Files changed (42) 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/views/mainwindow/components/passinfowidget/helpers.rb +26 -0
  6. data/lib/pass-qt/app/{components/passinfowidget.rb → views/mainwindow/components/passinfowidget/ui.rb} +21 -86
  7. data/lib/pass-qt/app/views/mainwindow/components/passinfowidget.rb +75 -0
  8. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/funcs/filter.rb +45 -0
  9. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/funcs/refresh.rb +58 -0
  10. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/funcs.rb +2 -0
  11. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/helpers.rb +18 -0
  12. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget/treewidget/ui.rb +36 -0
  13. data/lib/pass-qt/app/{components → views/mainwindow/components}/passlistwidget/treewidget.rb +12 -54
  14. data/lib/pass-qt/app/{components/passlistwidget.rb → views/mainwindow/components/passlistwidget/ui.rb} +13 -47
  15. data/lib/pass-qt/app/views/mainwindow/components/passlistwidget.rb +45 -0
  16. data/lib/pass-qt/app/views/mainwindow/ui.rb +39 -0
  17. data/lib/pass-qt/app/views/mainwindow.rb +5 -61
  18. data/lib/pass-qt/app/views/newonetimepassworddialog/ui.rb +90 -0
  19. data/lib/pass-qt/app/views/newonetimepassworddialog.rb +15 -93
  20. data/lib/pass-qt/app/views/newpassworddialog/ui.rb +111 -0
  21. data/lib/pass-qt/app/views/newpassworddialog.rb +18 -117
  22. data/lib/pass-qt/app.rb +2 -2
  23. data/lib/pass-qt/config/initializers/qt6.rb +1 -1
  24. data/lib/pass-qt/lib/{contrib/sighandler.rb → ctrlc/handler.rb} +6 -4
  25. data/lib/pass-qt/lib/ctrlc.rb +1 -0
  26. data/lib/pass-qt/lib/pass/{clients → backend}/gopass.rb +4 -4
  27. data/lib/pass-qt/lib/pass/{clients → backend}/pass.rb +6 -6
  28. data/lib/pass-qt/lib/pass/backend.rb +2 -0
  29. data/lib/pass-qt/lib/{contrib → pass}/process.rb +1 -1
  30. data/lib/pass-qt/lib/pass.rb +13 -11
  31. data/lib/pass-qt/lib.rb +1 -1
  32. data/lib/pass-qt/version.rb +1 -1
  33. metadata +23 -17
  34. data/lib/pass-qt/app/assets/README.md +0 -5
  35. data/lib/pass-qt/app/assets/app.svg +0 -1
  36. data/lib/pass-qt/app/components/passinfowidget/helpers.rb +0 -26
  37. data/lib/pass-qt/app/components/passlistwidget/treewidget/helpers.rb +0 -18
  38. data/lib/pass-qt/app/components/passlistwidget/treewidget/treebuilder.rb +0 -46
  39. data/lib/pass-qt/app/components/passlistwidget/treewidget/treefilter.rb +0 -45
  40. data/lib/pass-qt/lib/contrib.rb +0 -2
  41. data/lib/pass-qt/lib/pass/clients.rb +0 -2
  42. /data/lib/pass-qt/app/{components.rb → views/mainwindow/components.rb} +0 -0
@@ -1,9 +1,11 @@
1
+ require_relative "treewidget/funcs"
1
2
  require_relative "treewidget/helpers"
2
- require_relative "treewidget/treebuilder"
3
- require_relative "treewidget/treefilter"
3
+ require_relative "treewidget/ui"
4
4
 
5
- class PassListWidget < RubyQt6::Bando::QWidget
5
+ class MainWindowPassListWidget < RubyQt6::Bando::QWidget
6
6
  class TreeWidget < RubyQt6::Bando::QTreeWidget
7
+ DataItem = Struct.new(:passname, :treewidgetitem)
8
+
7
9
  q_object do
8
10
  signal "nil_selected(QString)"
9
11
  signal "passfile_selected(QString,QString)"
@@ -23,68 +25,24 @@ class PassListWidget < RubyQt6::Bando::QWidget
23
25
  @dataitems = {}
24
26
 
25
27
  initialize_actions
26
-
27
28
  current_item_changed.connect(self, :_on_current_item_changed)
28
29
  end
29
30
 
30
31
  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
-
32
+ menu = initialize_context_menu
45
33
  menu.exec(evt.global_pos)
46
34
  end
47
35
 
48
36
  def refresh(store, selected_passname: nil)
49
- @store = store
50
- @dataitems = {}
51
-
52
- builder = TreeBuilder.new
53
- builder.perform(self, @store, @dataitems)
54
-
55
- expand_all
56
- if selected_passname.nil?
57
- set_current_item(nil)
58
- else
59
- @dataitems.each do |_, item|
60
- next if item.passname != selected_passname
61
- set_current_item(item.treewidgetitem)
62
- break
63
- end
64
- end
37
+ refresh_imp(store, selected_passname:)
65
38
  end
66
39
 
67
- def update_passname_filter(text)
68
- filter = TreeFilter.new
69
- filter.perform(self, @dataitems, text)
40
+ def filter(text)
41
+ filter_imp(text)
70
42
  end
71
43
 
72
44
  private
73
45
 
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
46
  def _on_current_item_changed(curr, _prev)
89
47
  if curr.nil?
90
48
  nil_selected.emit(@store)
@@ -93,7 +51,7 @@ class PassListWidget < RubyQt6::Bando::QWidget
93
51
 
94
52
  filepath = curr.data(1, Qt::DisplayRole).value
95
53
  dataitem = @dataitems[filepath]
96
- Helpers.passfile?(filepath) ?
54
+ hlpr_passfile?(filepath) ?
97
55
  passfile_selected.emit(@store, dataitem.passname) :
98
56
  passfolder_selected.emit(@store, dataitem.passname)
99
57
  end
@@ -102,7 +60,7 @@ class PassListWidget < RubyQt6::Bando::QWidget
102
60
  item = selected_items[0]
103
61
  if item
104
62
  filepath = item.data(1, Qt::DisplayRole).value
105
- folder = Helpers.folderpath(@store, QFileInfo.new(filepath))
63
+ folder = hlpr_folderpath(@store, QFileInfo.new(filepath))
106
64
  folder = "" if folder == "."
107
65
  else
108
66
  folder = ""
@@ -118,7 +76,7 @@ class PassListWidget < RubyQt6::Bando::QWidget
118
76
  item = selected_items[0]
119
77
  if item
120
78
  filepath = item.data(1, Qt::DisplayRole).value
121
- folder = Helpers.folderpath(@store, QFileInfo.new(filepath))
79
+ folder = hlpr_folderpath(@store, QFileInfo.new(filepath))
122
80
  folder = "" if folder == "."
123
81
  else
124
82
  folder = ""
@@ -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
@@ -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.filter(text)
44
+ end
45
+ end
@@ -0,0 +1,39 @@
1
+ class MainWindow < RubyQt6::Bando::QMainWindow
2
+ private
3
+
4
+ def initialize_ui
5
+ initialize_toolbar
6
+ initialize_central_widget
7
+
8
+ set_context_menu_policy(Qt::NoContextMenu)
9
+ end
10
+
11
+ def initialize_toolbar
12
+ browse_action = QAction.new(QIcon.from_theme(QIcon::ThemeIcon::Computer), "Browse", self)
13
+ browse_action.set_tool_tip("Browse password stores")
14
+ browse_action.triggered.connect(self, :_on_browse_action_triggered)
15
+
16
+ toolbar = add_tool_bar("ToolBar")
17
+ toolbar.set_object_name("mainwindow_toolbar")
18
+ toolbar.set_movable(false)
19
+ toolbar.add_action(browse_action)
20
+ end
21
+
22
+ def initialize_central_widget
23
+ @passlistwidget = MainWindowPassListWidget.new
24
+ @passinfowidget = MainWindowPassInfoWidget.new
25
+
26
+ @passlistwidget.store_changed.connect(@passinfowidget, :activate_infocard)
27
+ @passlistwidget.nil_selected.connect(@passinfowidget, :activate_infocard)
28
+ @passlistwidget.passfile_selected.connect(@passinfowidget, :activate_passfilecard)
29
+ @passlistwidget.passfolder_selected.connect(@passinfowidget, :activate_passfoldercard)
30
+
31
+ centralwidget = QWidget.new
32
+ mainlayout = QHBoxLayout.new(centralwidget)
33
+ mainlayout.add_widget(@passlistwidget)
34
+ mainlayout.add_widget(@passinfowidget)
35
+ mainlayout.set_stretch(0, 2)
36
+ mainlayout.set_stretch(1, 3)
37
+ set_central_widget(centralwidget)
38
+ end
39
+ end
@@ -1,84 +1,28 @@
1
+ require_relative "mainwindow/components"
2
+ require_relative "mainwindow/ui"
3
+
1
4
  class MainWindow < RubyQt6::Bando::QMainWindow
2
5
  q_object do
3
6
  slot "_on_browse_action_triggered()"
4
- slot "_on_browsestoresdialog_stores_changed()"
5
- slot "_on_passlistwidget_store_changed(QString)"
6
- slot "_on_passlistwidget_nil_selected(QString)"
7
- slot "_on_passlistwidget_passfile_selected(QString,QString)"
8
- slot "_on_passlistwidget_passfolder_selected(QString,QString)"
9
7
  end
10
8
 
11
9
  def initialize
12
10
  super
13
11
 
14
- initialize_toolbar
15
- initialize_central_widget
16
-
17
- set_context_menu_policy(Qt::NoContextMenu)
12
+ initialize_ui
18
13
  PassQt.settings.GET_mainwindow_geometry_and_restore_to(self)
19
14
  end
20
15
 
21
16
  def close_event(evt)
22
17
  PassQt.settings.PUT_mainwindow_geometry(self)
23
-
24
18
  _close_event(evt)
25
19
  end
26
20
 
27
21
  private
28
22
 
29
- def initialize_toolbar
30
- browse_action = QAction.new(QIcon.from_theme(QIcon::ThemeIcon::Computer), "Browse", self)
31
- browse_action.set_tool_tip("Browse password stores")
32
- browse_action.triggered.connect(self, :_on_browse_action_triggered)
33
-
34
- toolbar = add_tool_bar("ToolBar")
35
- toolbar.set_object_name("mainwindow_toolbar")
36
- toolbar.set_movable(false)
37
- toolbar.add_action(browse_action)
38
- end
39
-
40
- def initialize_central_widget
41
- @passlistwidget = PassListWidget.new
42
- @passlistwidget.store_changed.connect(self, :_on_passlistwidget_store_changed)
43
- @passlistwidget.nil_selected.connect(self, :_on_passlistwidget_nil_selected)
44
- @passlistwidget.passfile_selected.connect(self, :_on_passlistwidget_passfile_selected)
45
- @passlistwidget.passfolder_selected.connect(self, :_on_passlistwidget_passfolder_selected)
46
-
47
- @passinfowidget = PassInfoWidget.new
48
-
49
- centralwidget = QWidget.new
50
- mainlayout = QHBoxLayout.new(centralwidget)
51
- mainlayout.add_widget(@passlistwidget)
52
- mainlayout.add_widget(@passinfowidget)
53
- mainlayout.set_stretch(0, 2)
54
- mainlayout.set_stretch(1, 3)
55
-
56
- set_central_widget(centralwidget)
57
- end
58
-
59
23
  def _on_browse_action_triggered
60
24
  dialog = BrowseStoresDialog.new
61
- dialog.stores_changed.connect(self, :_on_browsestoresdialog_stores_changed)
25
+ dialog.stores_changed.connect(@passlistwidget, :refresh)
62
26
  dialog.show
63
27
  end
64
-
65
- def _on_browsestoresdialog_stores_changed
66
- @passlistwidget.refresh
67
- end
68
-
69
- def _on_passlistwidget_store_changed(_store)
70
- @passinfowidget.use_infocard
71
- end
72
-
73
- def _on_passlistwidget_nil_selected(_store)
74
- @passinfowidget.use_infocard
75
- end
76
-
77
- def _on_passlistwidget_passfile_selected(store, passname)
78
- @passinfowidget.use_passfilecard(store, passname)
79
- end
80
-
81
- def _on_passlistwidget_passfolder_selected(store, passname)
82
- @passinfowidget.use_passfoldercard(store, passname)
83
- end
84
28
  end
@@ -0,0 +1,90 @@
1
+ class NewOneTimePasswordDialog < RubyQt6::Bando::QDialog
2
+ private
3
+
4
+ def initialize_ui
5
+ initialize_form
6
+ initialize_btngroup
7
+ initialize_layout
8
+
9
+ set_attribute(Qt::WA_DeleteOnClose)
10
+ set_modal(true)
11
+ end
12
+
13
+ def initialize_form
14
+ titlelabel = QLabel.new("<center><b>Insert New OTP Password</b></center>")
15
+
16
+ @errinfolabel = QLabel.new("")
17
+ @errinfolabel.set_style_sheet("background: white; color: red; padding: 8px; margin: 4px;")
18
+ @errinfolabel.set_hidden(true)
19
+
20
+ placeholder = (@folder == "") ? "example.com-otp" : "#{@folder}/example.com-otp"
21
+ @passnamelabel = initialize_form_label("File")
22
+ @passnameinput = initialize_form_inputfield(placeholder)
23
+ @passnameinput.set_text(placeholder)
24
+ set_focus_proxy(@passnameinput)
25
+
26
+ @passwordlabel = initialize_form_label("OTP URI")
27
+ @passwordinput = initialize_form_inputfield("otpauth://totp/GitHub...")
28
+
29
+ @form = QWidget.new
30
+ @form.set_object_name("newonetimepassworddialog_form")
31
+ @form.set_style_sheet("
32
+ #newonetimepassworddialog_form {
33
+ min-width: 600px;
34
+ }
35
+ ")
36
+
37
+ layout = QGridLayout.new(@form)
38
+ layout.add_widget(titlelabel, 0, 0, 1, 2)
39
+ layout.set_row_minimum_height(1, 10)
40
+ layout.add_widget(@errinfolabel, 2, 0, 1, 2)
41
+ layout.add_widget(@passnamelabel, 3, 0)
42
+ layout.add_widget(@passnameinput, 3, 1)
43
+ layout.add_widget(@passwordlabel, 4, 0)
44
+ layout.add_widget(@passwordinput, 4, 1)
45
+ end
46
+
47
+ def initialize_form_label(text)
48
+ label = QLabel.new(text)
49
+ label.set_alignment(Qt::AlignRight)
50
+ label.set_style_sheet("min-width: 80px; padding-right: 4px;")
51
+ label
52
+ end
53
+
54
+ def initialize_form_inputfield(placeholder)
55
+ input = QLineEdit.new
56
+ input.set_placeholder_text(placeholder)
57
+ input
58
+ end
59
+
60
+ def initialize_btngroup
61
+ @btngroup = QDialogButtonBox.new(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal)
62
+ @btngroup.accepted.connect(self, :_on_okbutton_clicked)
63
+ @btngroup.rejected.connect(self, :_on_cancelbutton_clicked)
64
+
65
+ okbutton = @btngroup.button(QDialogButtonBox::Ok)
66
+ okbutton.set_text("Create")
67
+ okbutton.set_default(true)
68
+ okbutton.set_auto_default(true)
69
+
70
+ cancelbutton = @btngroup.button(QDialogButtonBox::Cancel)
71
+ cancelbutton.set_auto_default(true)
72
+ end
73
+
74
+ def initialize_layout
75
+ mainlayout = QVBoxLayout.new(self)
76
+ mainlayout.add_widget(@form)
77
+ mainlayout.add_widget(@btngroup)
78
+ end
79
+
80
+ def update_form_errinfo(info)
81
+ if info.empty?
82
+ @errinfolabel.set_text("")
83
+ @errinfolabel.set_hidden(true)
84
+ return
85
+ end
86
+
87
+ @errinfolabel.set_text(info)
88
+ @errinfolabel.set_hidden(false)
89
+ end
90
+ end
@@ -1,3 +1,5 @@
1
+ require_relative "newonetimepassworddialog/ui"
2
+
1
3
  class NewOneTimePasswordDialog < RubyQt6::Bando::QDialog
2
4
  q_object do
3
5
  slot "_on_okbutton_clicked()"
@@ -11,92 +13,26 @@ class NewOneTimePasswordDialog < RubyQt6::Bando::QDialog
11
13
  @folder = folder
12
14
  @on_success = on_success
13
15
 
14
- initialize_form
15
- initialize_btngroup
16
-
17
- mainlayout = QVBoxLayout.new(self)
18
- mainlayout.add_widget(@form)
19
- mainlayout.add_widget(@btngroup)
20
-
21
- set_attribute(Qt::WA_DeleteOnClose)
22
- set_modal(true)
16
+ initialize_ui
23
17
  end
24
18
 
25
19
  private
26
20
 
27
- def initialize_form
28
- titlelabel = QLabel.new("<center><b>Insert New OTP Password</b></center>")
29
-
30
- @errinfolabel = QLabel.new("")
31
- @errinfolabel.set_style_sheet("background: white; color: red; padding: 8px; margin: 4px;")
32
- @errinfolabel.set_hidden(true)
33
-
34
- placeholder = (@folder == "") ? "example.com-otp" : "#{@folder}/example.com-otp"
35
- @passnamelabel = initialize_form_label("File")
36
- @passnameinput = initialize_form_inputfield(placeholder)
37
- @passnameinput.set_text(placeholder)
38
- set_focus_proxy(@passnameinput)
39
-
40
- @passwordlabel = initialize_form_label("OTP URI")
41
- @passwordinput = initialize_form_inputfield("otpauth://totp/GitHub...")
42
-
43
- @form = QWidget.new
44
- @form.set_object_name("newonetimepassworddialog_form")
45
- @form.set_style_sheet("
46
- #newonetimepassworddialog_form {
47
- min-width: 600px;
48
- }
49
- ")
50
-
51
- layout = QGridLayout.new(@form)
52
- layout.add_widget(titlelabel, 0, 0, 1, 2)
53
- layout.set_row_minimum_height(1, 10)
54
- layout.add_widget(@errinfolabel, 2, 0, 1, 2)
55
- layout.add_widget(@passnamelabel, 3, 0)
56
- layout.add_widget(@passnameinput, 3, 1)
57
- layout.add_widget(@passwordlabel, 4, 0)
58
- layout.add_widget(@passwordinput, 4, 1)
59
- end
60
-
61
- def initialize_form_label(text)
62
- label = QLabel.new(text)
63
- label.set_alignment(Qt::AlignRight)
64
- label.set_style_sheet("min-width: 80px; padding-right: 4px;")
65
- label
66
- end
67
-
68
- def initialize_form_inputfield(placeholder)
69
- input = QLineEdit.new
70
- input.set_placeholder_text(placeholder)
71
- input
72
- end
73
-
74
- def initialize_btngroup
75
- @btngroup = QDialogButtonBox.new(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal)
76
- @btngroup.accepted.connect(self, :_on_okbutton_clicked)
77
- @btngroup.rejected.connect(self, :_on_cancelbutton_clicked)
78
-
79
- okbutton = @btngroup.button(QDialogButtonBox::Ok)
80
- okbutton.set_text("Create")
81
- okbutton.set_default(true)
82
- okbutton.set_auto_default(true)
83
-
84
- cancelbutton = @btngroup.button(QDialogButtonBox::Cancel)
85
- cancelbutton.set_auto_default(true)
86
- end
87
-
88
- def update_form_errinfo(info)
89
- if info.empty?
90
- @errinfolabel.set_text("")
91
- @errinfolabel.set_hidden(true)
92
- return
93
- end
21
+ def _on_okbutton_clicked
22
+ return unless _on_okbutton_clicked_validate_form
94
23
 
95
- @errinfolabel.set_text(info)
96
- @errinfolabel.set_hidden(false)
24
+ store = @store
25
+ passname = @passnameinput.text
26
+ password = @passwordinput.text
27
+ Pass.otp_insert(store, passname, password, on_success: ->(_) {
28
+ @on_success.call(passname)
29
+ close
30
+ }, on_failure: ->(data) {
31
+ update_form_errinfo(data["stderr"].strip)
32
+ })
97
33
  end
98
34
 
99
- def validate_form
35
+ def _on_okbutton_clicked_validate_form
100
36
  update_form_errinfo("")
101
37
 
102
38
  {
@@ -112,20 +48,6 @@ class NewOneTimePasswordDialog < RubyQt6::Bando::QDialog
112
48
  true
113
49
  end
114
50
 
115
- def _on_okbutton_clicked
116
- return unless validate_form
117
-
118
- store = @store
119
- passname = @passnameinput.text
120
- password = @passwordinput.text
121
- Pass.otp_insert(store, passname, password, on_success: ->(_) {
122
- @on_success.call(passname)
123
- close
124
- }, on_failure: ->(data) {
125
- update_form_errinfo(data["stderr"].strip)
126
- })
127
- end
128
-
129
51
  def _on_cancelbutton_clicked
130
52
  close
131
53
  end
@@ -0,0 +1,111 @@
1
+ class NewPasswordDialog < RubyQt6::Bando::QDialog
2
+ private
3
+
4
+ def initialize_ui
5
+ initialize_form
6
+ initialize_btngroup
7
+ initialize_layout
8
+
9
+ set_attribute(Qt::WA_DeleteOnClose)
10
+ set_modal(true)
11
+ end
12
+
13
+ def initialize_form
14
+ titlelabel = QLabel.new("<center><b>Insert New Password</b></center>")
15
+
16
+ @errinfolabel = QLabel.new("")
17
+ @errinfolabel.set_style_sheet("background: white; color: red; padding: 8px; margin: 4px;")
18
+ @errinfolabel.set_hidden(true)
19
+
20
+ placeholder = (@folder == "") ? "example.com" : "#{@folder}/example.com"
21
+ @passnamelabel = initialize_form_label("File")
22
+ @passnameinput = initialize_form_inputfield(placeholder)
23
+ @passnameinput.set_text(placeholder)
24
+ set_focus_proxy(@passnameinput)
25
+
26
+ @passwordlabel = initialize_form_label("Password")
27
+ @passwordinput = initialize_form_inputfield("")
28
+ initialize_form_inputfield_viewaction(@passwordinput)
29
+
30
+ @passwordinput.set_echo_mode(QLineEdit::Password)
31
+ Pass.pwgen(16, on_success: ->(data) {
32
+ @passwordinput.set_text(data["stdout"].lines[0].strip)
33
+ }, on_failure: ->(_) {})
34
+
35
+ @usernamelabel = initialize_form_label("Username")
36
+ @usernameinput = initialize_form_inputfield("johndoe")
37
+
38
+ @websitelabel = initialize_form_label("Website")
39
+ @websiteinput = initialize_form_inputfield("https://github.com/login")
40
+
41
+ @form = QWidget.new
42
+ @form.set_object_name("newpassworddialog_form")
43
+ @form.set_style_sheet("
44
+ #newpassworddialog_form {
45
+ min-width: 600px;
46
+ }
47
+ ")
48
+
49
+ layout = QGridLayout.new(@form)
50
+ layout.add_widget(titlelabel, 0, 0, 1, 2)
51
+ layout.set_row_minimum_height(1, 10)
52
+ layout.add_widget(@errinfolabel, 2, 0, 1, 2)
53
+ layout.add_widget(@passnamelabel, 3, 0)
54
+ layout.add_widget(@passnameinput, 3, 1)
55
+ layout.add_widget(@usernamelabel, 4, 0)
56
+ layout.add_widget(@usernameinput, 4, 1)
57
+ layout.add_widget(@passwordlabel, 5, 0)
58
+ layout.add_widget(@passwordinput, 5, 1)
59
+ layout.add_widget(@websitelabel, 6, 0)
60
+ layout.add_widget(@websiteinput, 6, 1)
61
+ end
62
+
63
+ def initialize_form_label(text)
64
+ label = QLabel.new(text)
65
+ label.set_alignment(Qt::AlignRight)
66
+ label.set_style_sheet("min-width: 80px; padding-right: 4px;")
67
+ label
68
+ end
69
+
70
+ def initialize_form_inputfield(placeholder)
71
+ input = QLineEdit.new
72
+ input.set_placeholder_text(placeholder)
73
+ input
74
+ end
75
+
76
+ def initialize_form_inputfield_viewaction(input)
77
+ action = input.add_action(QIcon.from_theme(QIcon::ThemeIcon::DocumentPrintPreview), QLineEdit::TrailingPosition)
78
+ action.triggered.connect(self, :_on_view_action_triggered)
79
+ end
80
+
81
+ def initialize_btngroup
82
+ @btngroup = QDialogButtonBox.new(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal)
83
+ @btngroup.accepted.connect(self, :_on_okbutton_clicked)
84
+ @btngroup.rejected.connect(self, :_on_cancelbutton_clicked)
85
+
86
+ okbutton = @btngroup.button(QDialogButtonBox::Ok)
87
+ okbutton.set_text("Create")
88
+ okbutton.set_default(true)
89
+ okbutton.set_auto_default(true)
90
+
91
+ cancelbutton = @btngroup.button(QDialogButtonBox::Cancel)
92
+ cancelbutton.set_auto_default(true)
93
+ end
94
+
95
+ def initialize_layout
96
+ mainlayout = QVBoxLayout.new(self)
97
+ mainlayout.add_widget(@form)
98
+ mainlayout.add_widget(@btngroup)
99
+ end
100
+
101
+ def update_form_errinfo(info)
102
+ if info.empty?
103
+ @errinfolabel.set_text("")
104
+ @errinfolabel.set_hidden(true)
105
+ return
106
+ end
107
+
108
+ @errinfolabel.set_text(info)
109
+ @errinfolabel.set_hidden(false)
110
+ end
111
+ end