new application add ui

This commit is contained in:
Bilal Elmoussaoui 2016-06-02 20:06:50 +02:00
parent 958c49c6c5
commit 35fcafbae0
9 changed files with 245 additions and 356 deletions

View file

@ -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

View file

@ -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

View 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()

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -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):

View file

@ -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()

View file

@ -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):
"""