mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 08:44:40 +01:00
new application add ui
This commit is contained in:
parent
958c49c6c5
commit
35fcafbae0
9 changed files with 245 additions and 356 deletions
|
@ -45,7 +45,6 @@ class Application(Gtk.Application):
|
|||
self.cfg = SettingsReader()
|
||||
if self.cfg.read("state", "login"):
|
||||
self.locked = True
|
||||
GObject.threads_init()
|
||||
provider = Gtk.CssProvider()
|
||||
css_file = self.pkgdatadir + "/data/style.css"
|
||||
try:
|
||||
|
@ -127,11 +126,12 @@ class Application(Gtk.Application):
|
|||
"""
|
||||
Shows settings window
|
||||
"""
|
||||
if not self.settings_window:
|
||||
self.settings_window = SettingsWindow(self.win)
|
||||
else:
|
||||
self.settings_window.show()
|
||||
|
||||
try:
|
||||
settings_window = SettingsWindow(self.win)
|
||||
settings_window.show_window()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def on_quit(self, *args):
|
||||
"""
|
||||
Close the application, stops all threads
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
appdir = $(pythondir)/TwoFactorAuth/widgets
|
||||
|
||||
app_PYTHON = \
|
||||
add_authenticator.py \
|
||||
add_application.py \
|
||||
confirmation.py \
|
||||
listrow.py \
|
||||
authenticator_logo.py \
|
||||
applications_list.py \
|
||||
change_password.py \
|
||||
settings.py \
|
||||
window.py
|
||||
|
|
155
TwoFactorAuth/widgets/add_application.py
Normal file
155
TwoFactorAuth/widgets/add_application.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
from gi import require_version
|
||||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
import logging
|
||||
from TwoFactorAuth.widgets.applications_list import ApplicationChooserWindow
|
||||
from TwoFactorAuth.models.code import Code
|
||||
from TwoFactorAuth.models.authenticator import Authenticator
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
class AddApplication(Gtk.Window):
|
||||
selected_image = None
|
||||
hb = Gtk.HeaderBar()
|
||||
step = 1
|
||||
|
||||
logo_image = Gtk.Image(xalign=0)
|
||||
secret_code = Gtk.Entry()
|
||||
name_entry = Gtk.Entry()
|
||||
|
||||
def __init__(self, window):
|
||||
self.parent = window
|
||||
self.generate_window()
|
||||
self.generate_components()
|
||||
self.generate_header_bar()
|
||||
|
||||
def generate_window(self):
|
||||
self.win = Gtk.Window(type=Gtk.WindowType.TOPLEVEL, title=_("Add a new application"),
|
||||
modal=True, destroy_with_parent=True)
|
||||
self.win.connect("destroy", self.close_window)
|
||||
self.win.resize(410, 300)
|
||||
self.win.set_border_width(18)
|
||||
self.win.set_size_request(410, 300)
|
||||
self.win.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.win.set_resizable(False)
|
||||
self.win.set_transient_for(self.parent)
|
||||
self.win.connect("key_press_event", self.on_key_press)
|
||||
|
||||
def show_window(self):
|
||||
if self.step == 1:
|
||||
applications_choose_window = ApplicationChooserWindow(self)
|
||||
applications_choose_window.show_window()
|
||||
self.step = 2
|
||||
else:
|
||||
self.win.show_all()
|
||||
|
||||
def on_key_press(self, key, key_event):
|
||||
"""
|
||||
Keyboard Listener handler
|
||||
"""
|
||||
if Gdk.keyval_name(key_event.keyval) == "Escape":
|
||||
self.close_window()
|
||||
|
||||
def update_logo(self, image):
|
||||
"""
|
||||
Update image logo
|
||||
"""
|
||||
directory = self.parent.app.pkgdatadir + "/data/logos/"
|
||||
self.selected_image = image
|
||||
auth_icon = Authenticator.get_auth_icon(image, self.parent.app.pkgdatadir)
|
||||
self.logo_image.clear()
|
||||
self.logo_image.set_from_pixbuf(auth_icon)
|
||||
|
||||
def add_application(self, *args):
|
||||
"""
|
||||
Add a new application to the database
|
||||
"""
|
||||
name_entry = self.name_entry.get_text()
|
||||
secret_entry = self.secret_code.get_text()
|
||||
image_entry = self.selected_image if self.selected_image else "image-missing"
|
||||
try:
|
||||
self.parent.app.auth.add_application(name_entry, secret_entry,
|
||||
image_entry)
|
||||
uid = self.parent.app.auth.get_latest_id()
|
||||
self.parent.append_list_box(uid, name_entry, secret_entry, image_entry)
|
||||
self.parent.refresh_window()
|
||||
self.close_window()
|
||||
except Exception as e:
|
||||
logging.error("Error in adding a new application")
|
||||
logging.error(str(e))
|
||||
|
||||
def generate_components(self):
|
||||
"""
|
||||
Generate window components
|
||||
"""
|
||||
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
labels_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
logo_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
||||
hbox_title = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18)
|
||||
title_label = Gtk.Label()
|
||||
title_label.set_text(_("Application Name"))
|
||||
|
||||
hbox_title.pack_end(self.name_entry, False, True, 0)
|
||||
hbox_title.pack_end(title_label, False, True, 0)
|
||||
|
||||
hbox_two_factor = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18)
|
||||
two_factor_label = Gtk.Label()
|
||||
two_factor_label.set_text(_("Secret Code"))
|
||||
self.secret_code.connect("changed", self.validate_ascii_code)
|
||||
|
||||
hbox_two_factor.pack_end(self.secret_code, False, True, 0)
|
||||
hbox_two_factor.pack_end(two_factor_label, False, True, 0)
|
||||
|
||||
auth_icon = Authenticator.get_auth_icon("image-missing", self.parent.app.pkgdatadir)
|
||||
self.logo_image.set_from_pixbuf(auth_icon)
|
||||
self.logo_image.get_style_context().add_class("application-logo-add")
|
||||
logo_box.pack_start(self.logo_image, True, False, 6)
|
||||
logo_box.set_property("margin-bottom", 20)
|
||||
|
||||
vbox.add(hbox_title)
|
||||
vbox.add(hbox_two_factor)
|
||||
labels_box.pack_start(vbox, True, False, 6)
|
||||
main_box.pack_start(logo_box, False, True, 6)
|
||||
main_box.pack_start(labels_box, False, True, 6)
|
||||
self.win.add(main_box)
|
||||
|
||||
def validate_ascii_code(self, entry):
|
||||
"""
|
||||
Validate if the typed secret code is a valid ascii one
|
||||
"""
|
||||
ascii_code = entry.get_text().strip()
|
||||
is_valid = Code.is_valid(ascii_code)
|
||||
self.apply_button.set_sensitive(is_valid)
|
||||
if not is_valid and len(ascii_code) != 0:
|
||||
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic")
|
||||
else:
|
||||
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, None)
|
||||
|
||||
def generate_header_bar(self):
|
||||
"""
|
||||
Generate the header bar box
|
||||
"""
|
||||
left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
cancel_button = Gtk.Button.new_with_label(_("Cancel"))
|
||||
cancel_button.connect("clicked", self.close_window)
|
||||
cancel_button.get_style_context().add_class("destructive-action")
|
||||
left_box.add(cancel_button)
|
||||
|
||||
self.apply_button = Gtk.Button.new_with_label(_("Add"))
|
||||
self.apply_button.get_style_context().add_class("suggested-action")
|
||||
self.apply_button.connect("clicked", self.add_application)
|
||||
self.apply_button.set_sensitive(False)
|
||||
right_box.add(self.apply_button)
|
||||
|
||||
self.hb.pack_start(left_box)
|
||||
self.hb.pack_end(right_box)
|
||||
self.win.set_titlebar(self.hb)
|
||||
|
||||
def close_window(self, *args):
|
||||
"""
|
||||
Close the window
|
||||
"""
|
||||
self.win.destroy()
|
|
@ -1,262 +0,0 @@
|
|||
from gi import require_version
|
||||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
import logging
|
||||
from TwoFactorAuth.widgets.authenticator_logo import AuthenticatorLogoChooser
|
||||
from TwoFactorAuth.models.code import Code
|
||||
from TwoFactorAuth.models.authenticator import Authenticator
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
class AddAuthenticator(Gtk.Window):
|
||||
selected_image = None
|
||||
hb = Gtk.HeaderBar()
|
||||
|
||||
popover = Gtk.PopoverMenu.new()
|
||||
logo_image = Gtk.Image(xalign=0)
|
||||
secret_code = Gtk.Entry()
|
||||
name_entry = Gtk.Entry()
|
||||
|
||||
logo_finder_window = None
|
||||
provided_icons_window = None
|
||||
|
||||
def __init__(self, window):
|
||||
self.parent = window
|
||||
self.generate_window()
|
||||
self.generate_components()
|
||||
self.generate_header_bar()
|
||||
self.show_all()
|
||||
|
||||
def generate_window(self):
|
||||
Gtk.Window.__init__(self, title=_("Add a new application"),
|
||||
modal=True, destroy_with_parent=True)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.resize(430, 350)
|
||||
self.set_border_width(18)
|
||||
self.set_size_request(430, 350)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_resizable(False)
|
||||
self.set_transient_for(self.parent)
|
||||
self.connect("key_press_event", self.on_key_press)
|
||||
|
||||
def on_key_press(self, key, key_event):
|
||||
"""
|
||||
Keyboard Listener handler
|
||||
"""
|
||||
if Gdk.keyval_name(key_event.keyval) == "Escape":
|
||||
self.close_window()
|
||||
|
||||
def update_logo(self, image):
|
||||
"""
|
||||
Update image logo
|
||||
"""
|
||||
directory = self.parent.app.pkgdatadir + "/data/logos/"
|
||||
self.selected_image = image
|
||||
auth_icon = Authenticator.get_auth_icon(image, self.parent.app.pkgdatadir)
|
||||
self.logo_image.clear()
|
||||
self.logo_image.set_from_pixbuf(auth_icon)
|
||||
|
||||
def select_logo(self, event_box, event_button):
|
||||
"""
|
||||
Application logo selection, right & left mouse click event handling
|
||||
"""
|
||||
# Right click handling
|
||||
if event_button.button == 3:
|
||||
if self.popover.get_visible():
|
||||
self.popover.hide()
|
||||
else:
|
||||
self.popover.show_all()
|
||||
else:
|
||||
AuthenticatorLogoChooser(self)
|
||||
|
||||
def add_application(self, *args):
|
||||
"""
|
||||
Add a new application to the database
|
||||
"""
|
||||
name_entry = self.name_entry.get_text()
|
||||
secret_entry = self.secret_code.get_text()
|
||||
image_entry = self.selected_image if self.selected_image else "image-missing"
|
||||
try:
|
||||
self.parent.app.auth.add_application(name_entry, secret_entry,
|
||||
image_entry)
|
||||
uid = self.parent.app.auth.get_latest_id()
|
||||
self.parent.append_list_box(uid, name_entry, secret_entry, image_entry)
|
||||
self.parent.refresh_window()
|
||||
self.close_window()
|
||||
except Exception as e:
|
||||
logging.error("Error in adding a new application")
|
||||
logging.error(str(e))
|
||||
|
||||
def generate_components(self):
|
||||
"""
|
||||
Generate window components
|
||||
"""
|
||||
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
labels_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
logo_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
||||
hbox_title = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18)
|
||||
title_label = Gtk.Label()
|
||||
title_label.set_text(_("Application Name"))
|
||||
|
||||
hbox_title.pack_end(self.name_entry, False, True, 0)
|
||||
hbox_title.pack_end(title_label, False, True, 0)
|
||||
|
||||
hbox_two_factor = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18)
|
||||
two_factor_label = Gtk.Label()
|
||||
two_factor_label.set_text(_("Secret Code"))
|
||||
self.secret_code.connect("changed", self.validate_ascii_code)
|
||||
|
||||
hbox_two_factor.pack_end(self.secret_code, False, True, 0)
|
||||
hbox_two_factor.pack_end(two_factor_label, False, True, 0)
|
||||
|
||||
|
||||
self.hbox_icon_name = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18)
|
||||
icon_name_label = Gtk.Label()
|
||||
self.icon_name_entry = Gtk.Entry()
|
||||
icon_name_label.set_text(_("Icon name"))
|
||||
self.icon_name_entry.connect("changed", self.validate_icon_name)
|
||||
self.hbox_icon_name.pack_end(self.icon_name_entry, False, True, 0)
|
||||
self.hbox_icon_name.pack_end(icon_name_label, False, True, 0)
|
||||
self.hbox_icon_name.set_visible(False)
|
||||
self.hbox_icon_name.set_no_show_all(True)
|
||||
|
||||
logo_event = Gtk.EventBox()
|
||||
auth_icon = Authenticator.get_auth_icon("image-missing", self.parent.app.pkgdatadir)
|
||||
self.logo_image.set_from_pixbuf(auth_icon)
|
||||
self.logo_image.get_style_context().add_class("application-logo-add")
|
||||
logo_event.add(self.logo_image)
|
||||
logo_event.connect("button-press-event", self.select_logo)
|
||||
logo_box.pack_start(logo_event, True, False, 6)
|
||||
logo_box.set_property("margin-bottom", 20)
|
||||
|
||||
self.popover.get_style_context().add_class("choose-popover")
|
||||
self.popover.set_relative_to(self.logo_image)
|
||||
|
||||
pbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
pbox.set_property('margin', 12)
|
||||
pbox.set_property('width-request', 150)
|
||||
self.popover.add(pbox)
|
||||
|
||||
provided = Gtk.ModelButton.new()
|
||||
provided.set_label(_("Select from provided icons"))
|
||||
provided.connect("clicked", self.on_provided_click)
|
||||
pbox.pack_start(provided, False, False, 0)
|
||||
|
||||
file = Gtk.ModelButton.new()
|
||||
file.set_label(_("Select a file"))
|
||||
file.connect("clicked", self.on_file_clicked)
|
||||
pbox.pack_start(file, False, False, 0)
|
||||
|
||||
icon_name = Gtk.ModelButton.new()
|
||||
icon_name.set_label(_("Select an icon name"))
|
||||
icon_name.connect("clicked", self.on_icon_clicked)
|
||||
pbox.pack_start(icon_name, False, False, 0)
|
||||
|
||||
vbox.add(hbox_title)
|
||||
vbox.add(hbox_two_factor)
|
||||
vbox.add(self.hbox_icon_name)
|
||||
labels_box.pack_start(vbox, True, False, 6)
|
||||
main_box.pack_start(logo_box, False, True, 6)
|
||||
main_box.pack_start(labels_box, False, True, 6)
|
||||
self.add(main_box)
|
||||
|
||||
def validate_icon_name(self, entry):
|
||||
icon_name = entry.get_text()
|
||||
theme = Gtk.IconTheme.get_default()
|
||||
if theme.has_icon(icon_name):
|
||||
icon = theme.load_icon(icon_name, 48, 0)
|
||||
self.selected_image = icon_name
|
||||
else:
|
||||
icon = theme.load_icon("image-missing", 48, 0)
|
||||
self.logo_image.clear()
|
||||
self.logo_image.set_from_pixbuf(icon)
|
||||
|
||||
def validate_ascii_code(self, entry):
|
||||
"""
|
||||
Validate if the typed secret code is a valid ascii one
|
||||
"""
|
||||
ascii_code = entry.get_text().strip()
|
||||
is_valid = Code.is_valid(ascii_code)
|
||||
self.apply_button.set_sensitive(is_valid)
|
||||
if not is_valid and len(ascii_code) != 0:
|
||||
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic")
|
||||
else:
|
||||
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, None)
|
||||
|
||||
def on_provided_click(self, *args):
|
||||
"""
|
||||
Select an icon from provided ones
|
||||
"""
|
||||
if self.provided_icons_window:
|
||||
self.provided_icons_window.show()
|
||||
else:
|
||||
self.provided_icons_window = AuthenticatorLogoChooser(self)
|
||||
|
||||
def on_file_clicked(self, *args):
|
||||
""""
|
||||
Select an icon by filename
|
||||
"""
|
||||
dialog = Gtk.FileChooserDialog(_("Please choose a file"), self,
|
||||
Gtk.FileChooserAction.OPEN,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||||
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
|
||||
self.add_filters(dialog)
|
||||
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
self.update_logo(dialog.get_filename())
|
||||
dialog.destroy()
|
||||
|
||||
def on_icon_clicked(self, *args):
|
||||
"""
|
||||
Shows icon finder window
|
||||
select icon by icon name
|
||||
"""
|
||||
is_visible = self.hbox_icon_name.get_no_show_all()
|
||||
self.hbox_icon_name.set_visible(is_visible)
|
||||
self.hbox_icon_name.set_no_show_all(not is_visible)
|
||||
self.hbox_icon_name.show_all()
|
||||
|
||||
def add_filters(self, dialog):
|
||||
"""
|
||||
Add file filters to GtkFileChooser
|
||||
"""
|
||||
filter_png = Gtk.FileFilter()
|
||||
filter_png.set_name("PNG")
|
||||
filter_png.add_mime_type("image/png")
|
||||
dialog.add_filter(filter_png)
|
||||
|
||||
filter_svg = Gtk.FileFilter()
|
||||
filter_svg.set_name("SVG")
|
||||
filter_svg.add_mime_type("image/svg+xml")
|
||||
dialog.add_filter(filter_svg)
|
||||
|
||||
def generate_header_bar(self):
|
||||
"""
|
||||
Generate the header bar box
|
||||
"""
|
||||
left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
cancel_button = Gtk.Button.new_with_label(_("Cancel"))
|
||||
cancel_button.connect("clicked", self.close_window)
|
||||
cancel_button.get_style_context().add_class("destructive-action")
|
||||
left_box.add(cancel_button)
|
||||
|
||||
self.apply_button = Gtk.Button.new_with_label(_("Add"))
|
||||
self.apply_button.get_style_context().add_class("suggested-action")
|
||||
self.apply_button.connect("clicked", self.add_application)
|
||||
self.apply_button.set_sensitive(False)
|
||||
right_box.add(self.apply_button)
|
||||
|
||||
self.hb.pack_start(left_box)
|
||||
self.hb.pack_end(right_box)
|
||||
self.set_titlebar(self.hb)
|
||||
|
||||
def close_window(self, *args):
|
||||
"""
|
||||
Close the window
|
||||
"""
|
||||
self.hide()
|
||||
return True
|
|
@ -3,35 +3,37 @@ require_version("Gtk", "3.0")
|
|||
from gi.repository import Gtk, GLib, Gio, Gdk
|
||||
from TwoFactorAuth.models.authenticator import Authenticator
|
||||
from os import path, listdir
|
||||
import logging
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
class AuthenticatorLogoChooser(Gtk.Window):
|
||||
class ApplicationChooserWindow(Gtk.Window):
|
||||
|
||||
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
def __init__(self, window):
|
||||
self.parent = window
|
||||
directory = window.parent.app.pkgdatadir + "/data/logos/"
|
||||
self.logos = listdir(directory)
|
||||
self.logos.sort()
|
||||
self.window = window
|
||||
self.generate_window()
|
||||
self.generate_searchbar()
|
||||
self.generate_compenents()
|
||||
self.generate_headerbar()
|
||||
self.show_all()
|
||||
self.generate_search_bar()
|
||||
self.generate_components()
|
||||
self.generate_header_bar()
|
||||
|
||||
def generate_window(self):
|
||||
Gtk.Window.__init__(self, modal=True, destroy_with_parent=True)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.resize(380, 450)
|
||||
self.set_size_request(380, 450)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_resizable(False)
|
||||
self.set_transient_for(self.window.parent)
|
||||
self.connect("key_press_event", self.on_key_press)
|
||||
self.add(self.main_box)
|
||||
self.win = Gtk.Window(type=Gtk.WindowType.TOPLEVEL, modal=True, destroy_with_parent=True)
|
||||
self.win.connect("destroy", self.close_window)
|
||||
self.win.resize(410, 550)
|
||||
self.win.set_size_request(410, 550)
|
||||
self.win.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.win.set_resizable(False)
|
||||
self.win.set_transient_for(self.window.parent)
|
||||
self.win.connect("key_press_event", self.on_key_press)
|
||||
self.win.add(self.main_box)
|
||||
|
||||
def show_window(self):
|
||||
self.win.show_all()
|
||||
|
||||
def filter_func(self, row, data, notify_destroy):
|
||||
app_label = row.get_children()[0].get_children()[0].get_children()
|
||||
|
@ -82,15 +84,13 @@ class AuthenticatorLogoChooser(Gtk.Window):
|
|||
self.listbox.set_filter_func(
|
||||
lambda x, y, z: True, None, False)
|
||||
|
||||
def generate_searchbar(self):
|
||||
def generate_search_bar(self):
|
||||
self.search_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.search_entry = Gtk.Entry()
|
||||
self.search_entry.connect("changed", self.filter_logos)
|
||||
self.search_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,
|
||||
"system-search-symbolic")
|
||||
self.search_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY, "system-search-symbolic")
|
||||
|
||||
self.search_box.set_visible(False)
|
||||
self.search_box.set_no_show_all(True)
|
||||
|
@ -104,9 +104,10 @@ class AuthenticatorLogoChooser(Gtk.Window):
|
|||
if len(self.logos) > 0:
|
||||
img_path = self.logos[index]
|
||||
self.window.update_logo(img_path)
|
||||
self.parent.show_window()
|
||||
self.close_window()
|
||||
|
||||
def generate_compenents(self):
|
||||
def generate_components(self):
|
||||
box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
if len(self.logos) > 0:
|
||||
# Create a ScrolledWindow for installed applications
|
||||
|
@ -146,7 +147,7 @@ class AuthenticatorLogoChooser(Gtk.Window):
|
|||
self.listbox.add(row)
|
||||
i += 1
|
||||
|
||||
def generate_headerbar(self):
|
||||
def generate_header_bar(self):
|
||||
self.hb = Gtk.HeaderBar()
|
||||
|
||||
left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
@ -157,15 +158,14 @@ class AuthenticatorLogoChooser(Gtk.Window):
|
|||
cancel_button.get_style_context().add_class("destructive-action")
|
||||
left_box.add(cancel_button)
|
||||
|
||||
apply_button = Gtk.Button.new_with_label(_("Choose"))
|
||||
apply_button.get_style_context().add_class("suggested-action")
|
||||
apply_button.connect("clicked", self.select_logo)
|
||||
right_box.add(apply_button)
|
||||
next_button = Gtk.Button.new_with_label(_("Next"))
|
||||
next_button.get_style_context().add_class("suggested-action")
|
||||
next_button.connect("clicked", self.select_logo)
|
||||
right_box.add(next_button)
|
||||
|
||||
self.hb.pack_start(left_box)
|
||||
self.hb.pack_end(right_box)
|
||||
self.set_titlebar(self.hb)
|
||||
self.win.set_titlebar(self.hb)
|
||||
|
||||
def close_window(self, *args):
|
||||
self.hide()
|
||||
return True
|
||||
self.win.destroy()
|
|
@ -20,18 +20,21 @@ class PasswordWindow(Gtk.Window):
|
|||
self.generate_window()
|
||||
self.generate_components()
|
||||
self.generate_header_bar()
|
||||
self.show_all()
|
||||
|
||||
def generate_window(self):
|
||||
Gtk.Window.__init__(self, title=_("Change password"), modal=True, destroy_with_parent=True)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.resize(300, 100)
|
||||
self.set_border_width(18)
|
||||
self.set_size_request(300, 100)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_resizable(False)
|
||||
self.set_transient_for(self.parent)
|
||||
self.connect("key_press_event", self.on_key_press)
|
||||
self.win = Gtk.Window(type=Gtk.WindowType.TOPLEVEL, title=_("Change password"),
|
||||
modal=True, destroy_with_parent=True)
|
||||
self.win.connect("destroy", self.close_window)
|
||||
self.win.resize(300, 100)
|
||||
self.win.set_border_width(18)
|
||||
self.win.set_size_request(300, 100)
|
||||
self.win.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.win.set_resizable(False)
|
||||
self.win.set_transient_for(self.parent)
|
||||
self.win.connect("key_press_event", self.on_key_press)
|
||||
|
||||
def show_window(self):
|
||||
self.win.show_all()
|
||||
|
||||
def on_key_press(self, key, key_event):
|
||||
"""
|
||||
|
@ -81,7 +84,7 @@ class PasswordWindow(Gtk.Window):
|
|||
box.add(box_new2)
|
||||
|
||||
main_box.pack_start(box, False, True, 6)
|
||||
self.add(main_box)
|
||||
self.win.add(main_box)
|
||||
|
||||
def update_password(self, *args):
|
||||
"""
|
||||
|
@ -90,7 +93,7 @@ class PasswordWindow(Gtk.Window):
|
|||
password = sha256(self.new_entry.get_text().encode("utf-8")).hexdigest()
|
||||
self.cfg.update("password", password, "login")
|
||||
logging.debug("Password changed successfully")
|
||||
self.destroy()
|
||||
self.close_window()
|
||||
|
||||
def on_type_password(self, entry):
|
||||
"""
|
||||
|
@ -118,13 +121,10 @@ class PasswordWindow(Gtk.Window):
|
|||
else:
|
||||
old_is_ok = True
|
||||
if old_is_ok:
|
||||
self.old_entry.set_icon_from_icon_name(
|
||||
Gtk.EntryIconPosition.SECONDARY, "")
|
||||
self.old_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, None)
|
||||
if not are_diff:
|
||||
self.new_entry.set_icon_from_icon_name(
|
||||
Gtk.EntryIconPosition.SECONDARY, "")
|
||||
self.new2_entry.set_icon_from_icon_name(
|
||||
Gtk.EntryIconPosition.SECONDARY, "")
|
||||
self.new_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, None)
|
||||
self.new2_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, None)
|
||||
self.apply_button.set_sensitive(not are_diff and old_is_ok)
|
||||
|
||||
def generate_header_bar(self):
|
||||
|
@ -146,11 +146,10 @@ class PasswordWindow(Gtk.Window):
|
|||
|
||||
self.hb.pack_start(left_box)
|
||||
self.hb.pack_end(right_box)
|
||||
self.set_titlebar(self.hb)
|
||||
self.win.set_titlebar(self.hb)
|
||||
|
||||
def close_window(self, *args):
|
||||
"""
|
||||
Close the window
|
||||
"""
|
||||
self.hide()
|
||||
return True
|
||||
self.win.destroy()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from gi import require_version
|
||||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GObject
|
||||
from gi.repository import Gtk, GObject, GLib
|
||||
from TwoFactorAuth.models.code import Code
|
||||
from TwoFactorAuth.models.authenticator import Authenticator
|
||||
from TwoFactorAuth.models.settings import SettingsReader
|
||||
|
@ -41,7 +41,7 @@ class ListBoxRow(Thread):
|
|||
self.logo = logo
|
||||
self.create_row()
|
||||
self.start()
|
||||
GObject.timeout_add_seconds(1, self.refresh_listbox)
|
||||
GLib.timeout_add_seconds(1, self.refresh_listbox)
|
||||
|
||||
@staticmethod
|
||||
def get_id(row):
|
||||
|
|
|
@ -14,25 +14,25 @@ class SettingsWindow(Gtk.Window):
|
|||
auto_lock_switch = Gtk.CheckButton()
|
||||
password_button = Gtk.Button()
|
||||
|
||||
password_window = None
|
||||
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
self.cfg = SettingsReader()
|
||||
self.generate_window()
|
||||
self.generate_components()
|
||||
self.show_all()
|
||||
|
||||
def generate_window(self):
|
||||
Gtk.Window.__init__(self, title=_("Settings"),
|
||||
destroy_with_parent=True)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.resize(400, 300)
|
||||
self.set_size_request(400, 300)
|
||||
self.set_resizable(False)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_transient_for(self.parent)
|
||||
self.connect("key_press_event", self.on_key_press)
|
||||
self.win = Gtk.Window(title=_("Settings"),type=Gtk.WindowType.TOPLEVEL,
|
||||
destroy_with_parent=True, modal=True)
|
||||
self.win.connect("destroy", self.close_window)
|
||||
self.win.resize(410, 300)
|
||||
self.win.set_size_request(410, 300)
|
||||
self.win.set_resizable(False)
|
||||
self.win.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.win.set_transient_for(self.parent)
|
||||
self.win.connect("key_press_event", self.on_key_press)
|
||||
|
||||
def show_window(self):
|
||||
self.win.show_all()
|
||||
|
||||
def on_key_press(self, key, key_event):
|
||||
"""
|
||||
|
@ -45,14 +45,14 @@ class SettingsWindow(Gtk.Window):
|
|||
"""
|
||||
Generate all the components
|
||||
"""
|
||||
self.add(self.notebook)
|
||||
self.win.add(self.notebook)
|
||||
user_settings = self.generate_user_settings()
|
||||
user_settings.set_border_width(10)
|
||||
self.notebook.append_page(user_settings, Gtk.Label(_('Behavior')))
|
||||
self.notebook.append_page(user_settings, Gtk.Label().new(_('Behavior')))
|
||||
|
||||
login_settings = self.generate_login_settings()
|
||||
login_settings.set_border_width(10)
|
||||
self.notebook.append_page(login_settings, Gtk.Label(_('Account')))
|
||||
self.notebook.append_page(login_settings, Gtk.Label().new(_('Account')))
|
||||
|
||||
def generate_login_settings(self):
|
||||
"""
|
||||
|
@ -90,14 +90,15 @@ class SettingsWindow(Gtk.Window):
|
|||
|
||||
is_auto_lock_active = bool(self.cfg.read("auto-lock", "preferences"))
|
||||
auto_lock_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
auto_lock_label = Gtk.Label(_("Auto-lock the application (m):"))
|
||||
auto_lock_label = Gtk.Label().new(_("Auto-lock the application (m):"))
|
||||
self.auto_lock_switch.set_active(is_auto_lock_active)
|
||||
self.auto_lock_switch.connect("toggled", self.on_auto_lock_activated)
|
||||
|
||||
default_value = self.cfg.read("auto-lock-time", "preferences")
|
||||
if default_value < 1 or default_value > 10:
|
||||
default_value = 3
|
||||
adjustment = Gtk.Adjustment(default_value, 1, 10, 1, 1, 0)
|
||||
adjustment = Gtk.Adjustment(value=default_value, lower=1, upper=10,
|
||||
step_increment=1, page_increment=1, page_size=0)
|
||||
self.auto_lock_time.connect("value-changed", self.on_auto_lock_time_changed)
|
||||
self.auto_lock_time.set_adjustment(adjustment)
|
||||
self.auto_lock_time.set_sensitive(is_auto_lock_active)
|
||||
|
@ -108,11 +109,12 @@ class SettingsWindow(Gtk.Window):
|
|||
auto_lock_box.pack_start(self.auto_lock_time, False, True, 12)
|
||||
|
||||
time_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
time_label = Gtk.Label(_("Secret code generation time (s) :"))
|
||||
time_label = Gtk.Label().new(_("Secret code generation time (s) :"))
|
||||
default_value = self.cfg.read("refresh-time", "preferences")
|
||||
if default_value < 30 or default_value > 120:
|
||||
default_value = 30
|
||||
adjustment = Gtk.Adjustment(default_value, 10, 120, 1, 10, 0)
|
||||
adjustment = Gtk.Adjustment(value=default_value, lower=10, upper=120,
|
||||
step_increment=1, page_increment=10, page_size=0)
|
||||
self.time_spin_button.connect("value-changed", self.on_time_changed)
|
||||
self.time_spin_button.set_adjustment(adjustment)
|
||||
self.time_spin_button.set_value(default_value)
|
||||
|
@ -128,10 +130,8 @@ class SettingsWindow(Gtk.Window):
|
|||
"""
|
||||
Show a new password window
|
||||
"""
|
||||
if not self.password_window:
|
||||
self.password_window = PasswordWindow(self)
|
||||
else:
|
||||
self.password_window.show()
|
||||
pass_window = PasswordWindow(self)
|
||||
pass_window.show_window()
|
||||
|
||||
def on_time_changed(self, spin_button):
|
||||
"""
|
||||
|
@ -169,5 +169,4 @@ class SettingsWindow(Gtk.Window):
|
|||
"""
|
||||
Close the window
|
||||
"""
|
||||
self.hide()
|
||||
return True
|
||||
self.win.destroy()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from gi import require_version
|
||||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gio, Gdk, GObject
|
||||
from TwoFactorAuth.widgets.add_authenticator import AddAuthenticator
|
||||
from gi.repository import Gtk, Gio, Gdk, GObject, GLib
|
||||
from TwoFactorAuth.widgets.add_application import AddApplication
|
||||
from TwoFactorAuth.widgets.confirmation import ConfirmationMessage
|
||||
from TwoFactorAuth.widgets.listrow import ListBoxRow
|
||||
import logging
|
||||
|
@ -49,18 +49,18 @@ class Window(Gtk.ApplicationWindow):
|
|||
self.generate_no_apps_box()
|
||||
self.generate_login_form()
|
||||
self.refresh_window()
|
||||
GObject.timeout_add_seconds(60, self.refresh_counter)
|
||||
GLib.timeout_add_seconds(60, self.refresh_counter)
|
||||
|
||||
def generate_window(self, *args):
|
||||
"""
|
||||
Generate application window (Gtk.Window)
|
||||
"""
|
||||
Gtk.ApplicationWindow.__init__(self, Gtk.WindowType.TOPLEVEL,
|
||||
Gtk.ApplicationWindow.__init__(self, type=Gtk.WindowType.TOPLEVEL,
|
||||
application=self.app)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_wmclass(self.app.package, "TwoFactorAuth")
|
||||
self.resize(430, 550)
|
||||
self.set_size_request(430, 550)
|
||||
self.resize(410, 550)
|
||||
self.set_size_request(410, 550)
|
||||
self.set_resizable(False)
|
||||
self.connect("key_press_event", self.on_key_press)
|
||||
self.connect("delete-event", lambda x, y: self.app.on_quit())
|
||||
|
@ -364,10 +364,8 @@ class Window(Gtk.ApplicationWindow):
|
|||
"""
|
||||
Create add application window
|
||||
"""
|
||||
if self.add_application_window:
|
||||
self.add_application_window.show()
|
||||
else:
|
||||
self.add_application_window = AddAuthenticator(self)
|
||||
add_app = AddApplication(self)
|
||||
add_app.show_window()
|
||||
|
||||
def toggle_search_box(self, *args):
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue