mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-05 17:20:57 +01:00
Settings: switch to using Gtk.Template and ditch uneeded options
This commit is contained in:
parent
343d57462b
commit
3fb0d87c43
11 changed files with 638 additions and 320 deletions
|
@ -16,6 +16,7 @@
|
|||
<file compressed="true" preprocess="xml-stripblanks" alias="account_edit.ui">ui/account_edit.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks" alias="account_row.ui">ui/account_row.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks" alias="window.ui">window.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks" alias="settings.ui">settings.ui</file>
|
||||
|
||||
<!-- Default pre-shipped icons -->
|
||||
<file alias="amazon.svg">icons/hicolor/48x48/apps/amazon.svg</file>
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
about_dialog_conf = configuration_data()
|
||||
about_dialog_conf.set('APP_ID', application_id)
|
||||
about_dialog_conf.set('VERSION', meson.project_version())
|
||||
ui_config = configuration_data()
|
||||
ui_config.set('APP_ID', application_id)
|
||||
ui_config.set('VERSION', meson.project_version())
|
||||
|
||||
ui_preconfigured_files = files(
|
||||
'ui/about_dialog.ui.in',
|
||||
'ui/settings.ui.in',
|
||||
'ui/window.ui.in',
|
||||
)
|
||||
ui_dependencies = []
|
||||
foreach ui_file: ui_preconfigured_files
|
||||
ui_dependencies += configure_file(
|
||||
input: ui_file,
|
||||
output: '@BASENAME@',
|
||||
configuration: ui_config
|
||||
)
|
||||
endforeach
|
||||
|
||||
gnome.compile_resources(
|
||||
application_id,
|
||||
meson.project_name() + '.gresource.xml',
|
||||
gresource_bundle: true,
|
||||
install_dir: join_paths(get_option('datadir'), meson.project_name()),
|
||||
install: true,
|
||||
dependencies: [configure_file(
|
||||
input: 'ui/about_dialog.ui.in',
|
||||
output: 'about_dialog.ui',
|
||||
configuration: about_dialog_conf
|
||||
),
|
||||
configure_file(
|
||||
input: 'ui/window.ui.in',
|
||||
output: 'window.ui',
|
||||
configuration: about_dialog_conf
|
||||
)
|
||||
]
|
||||
dependencies: ui_dependencies
|
||||
)
|
||||
|
||||
# Install gschema
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
.account-row,
|
||||
.settings-box{
|
||||
padding: 6px;
|
||||
.settings-row{
|
||||
background-color: mix(@theme_base_color,@theme_bg_color,0.3);
|
||||
padding: 2px 8px;
|
||||
margin:0;
|
||||
border: 1px solid mix(@theme_base_color,@theme_fg_color,0.3);
|
||||
background-color: mix(@theme_base_color,@theme_bg_color,0.3);
|
||||
margin: 6px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
.account-row:last-child, .settings-row:last-child {
|
||||
border-bottom: 1px solid mix(@theme_base_color,@theme_fg_color,0.3);
|
||||
}
|
||||
|
||||
/* AccountsList */
|
||||
|
@ -16,9 +20,6 @@
|
|||
}
|
||||
|
||||
/* AccountRow */
|
||||
.account-row {
|
||||
padding:0;
|
||||
}
|
||||
.account-row .account-name-label{
|
||||
font-size: 13px;
|
||||
padding: 3px 6px;
|
||||
|
@ -27,6 +28,21 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
.settings-category-title{
|
||||
font-size:13px;
|
||||
font-weight:600;
|
||||
padding: 6px 3px;
|
||||
}
|
||||
|
||||
.settings-box-main-label{
|
||||
font-size:12px;
|
||||
}
|
||||
.settings-box-secondary-label{
|
||||
font-size:12px;
|
||||
color: mix(@theme_base_color,@theme_fg_color,0.6);
|
||||
}
|
||||
|
||||
|
||||
.application-name {
|
||||
font-size: 14px;
|
||||
|
@ -39,31 +55,7 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
.settings-box-main-label{
|
||||
font-size: 14px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.settings-box-secondary-label {
|
||||
font-size:12px;
|
||||
font-style:italic;
|
||||
color: mix(@theme_base_color,@theme_fg_color,0.6);
|
||||
padding: 3px 6px;
|
||||
}
|
||||
.settings-main-container{
|
||||
margin-left: 36px;
|
||||
margin-right: 36px;
|
||||
}
|
||||
|
||||
.loginwidget-sublabel{
|
||||
font-size: 12px;
|
||||
color: mix(@theme_base_color,@theme_fg_color,0.6);
|
||||
}
|
||||
.loginwidget-mainlabel{
|
||||
font-size: 18px;
|
||||
|
||||
}
|
||||
|
||||
/* Common */
|
||||
.progress-bar trough progress {
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
|
@ -72,3 +64,6 @@
|
|||
.progress-bar trough {
|
||||
border-radius: 0px
|
||||
}
|
||||
.app-notification{
|
||||
font-size:11px;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
<object class="GtkRevealer" id="notification">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">none</property>
|
||||
<child>
|
||||
<object class="GtkOverlay">
|
||||
<property name="visible">True</property>
|
||||
|
|
|
@ -13,11 +13,10 @@
|
|||
<property name="icon_name">document-edit-symbolic</property>
|
||||
</object>
|
||||
<template class="AccountRow" parent="GtkListBoxRow">
|
||||
<property name="width_request">100</property>
|
||||
<property name="height_request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="selectable">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
|
|
482
data/ui/settings.ui.in
Normal file
482
data/ui/settings.ui.in
Normal file
|
@ -0,0 +1,482 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<object class="GtkImage" id="previous_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">go-previous-symbolic</property>
|
||||
</object>
|
||||
<template class="SettingsWindow" parent="GtkWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="default_width">350</property>
|
||||
<property name="default_height">500</property>
|
||||
<property name="gravity">center</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="notification">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkOverlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="notification_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<style>
|
||||
<class name="app-notification"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="index">-1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="main_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">36</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Behaviour</property>
|
||||
<style>
|
||||
<class name="settings-category-title"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Dark theme</property>
|
||||
<style>
|
||||
<class name="settings-box-main-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Use a dark theme, if possible</property>
|
||||
<style>
|
||||
<class name="settings-box-secondary-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="dark_theme_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="state-set" handler="dark_theme_switch_state_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="settings-box"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="settings-row"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Lock the application</property>
|
||||
<style>
|
||||
<class name="settings-box-main-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Lock the application with a password</property>
|
||||
<style>
|
||||
<class name="settings-box-secondary-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="lock_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="state-set" handler="lock_switch_state_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="settings-box"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="settings-row"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">settings_view</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">@APP_ID@-symbolic</property>
|
||||
<property name="icon_size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="label" translatable="yes">Keep your accounts safer </property>
|
||||
<property name="ellipsize">end</property>
|
||||
<style>
|
||||
<class name="label-help"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="password_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="input_purpose">password</property>
|
||||
<signal name="changed" handler="password_entry_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Repeat Password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="repeat_password_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="input_purpose">password</property>
|
||||
<signal name="changed" handler="password_entry_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">password_view</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child type="title">
|
||||
<object class="GtkStack" id="headerbar_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Settings</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">headerbar_settings</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child type="center">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Authenticator Password</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="back_btn">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">previous_img</property>
|
||||
<signal name="clicked" handler="back_btn_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_btn">
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="save_btn_clicked" swapped="no"/>
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">headerbar_password</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
|
@ -170,7 +170,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="resource">/com/github/bilelmoussaoui/Authenticator/authenticator-symbolic.svg</property>
|
||||
<property name="icon_name">@APP_ID@-symbolic</property>
|
||||
<property name="icon_size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
|
@ -23,7 +23,7 @@ from gi import require_version
|
|||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gio, Gdk, GObject
|
||||
from .widgets import Window, WindowState, AboutDialog, import_json, export_json
|
||||
from .models import Database, Settings, Clipboard, Logger
|
||||
from .models import Database, Settings, Clipboard, Logger, Keyring
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
@ -40,7 +40,7 @@ class Application(Gtk.Application):
|
|||
GLib.set_prgname("Authenticator")
|
||||
self.connect("notify::is-locked", self.__is_locked_changed)
|
||||
self.alive = True
|
||||
Settings.get_default().bind("is-locked", self, "is_locked", Gio.SettingsBindFlags.GET)
|
||||
|
||||
self._menu = Gio.Menu()
|
||||
|
||||
def __is_locked_changed(self, *_):
|
||||
|
@ -63,7 +63,7 @@ class Application(Gtk.Application):
|
|||
Gtk.Application.do_startup(self)
|
||||
self.__generate_menu()
|
||||
self.__setup_actions()
|
||||
self.set_property("is-locked", Settings.get_default().can_be_locked)
|
||||
self.props.is_locked = Keyring.get_default().has_password()
|
||||
Application.__setup_css()
|
||||
|
||||
# Set the default night mode
|
||||
|
@ -126,7 +126,7 @@ class Application(Gtk.Application):
|
|||
self.__add_action("settings", self.__on_settings, "is_locked")
|
||||
self.__add_action("import_json", self.__on_import_json, "is_locked")
|
||||
self.__add_action("export_json", self.__on_export_json, "is_locked")
|
||||
if Settings.get_default().can_be_locked:
|
||||
if Keyring.get_default().has_password():
|
||||
self.__add_action("lock", self.__on_lock, "is_locked")
|
||||
|
||||
# Keyboard shortcuts. This includes actions defined in window.py.in
|
||||
|
|
|
@ -137,3 +137,8 @@ class Keyring:
|
|||
@staticmethod
|
||||
def has_password():
|
||||
return Keyring.get_password() is not None
|
||||
|
||||
@staticmethod
|
||||
def clear_password():
|
||||
schema = Keyring.get_default().password_schema
|
||||
Secret.password_clear_sync(schema, {}, None)
|
||||
|
|
|
@ -29,7 +29,7 @@ class Settings(Gio.Settings):
|
|||
instance = None
|
||||
# Settings schema
|
||||
SCHEMA = "@APP_ID@"
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Gio.Settings.__init__(self)
|
||||
|
||||
|
|
|
@ -19,293 +19,125 @@
|
|||
|
||||
from gettext import gettext as _
|
||||
|
||||
from gi import require_version
|
||||
|
||||
require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GObject
|
||||
from gi.repository import Gio, GLib, Gtk, GObject
|
||||
from .window import Window
|
||||
from ..models import Settings, Keyring
|
||||
|
||||
|
||||
class ClickableSettingsBox(Gtk.EventBox):
|
||||
|
||||
def __init__(self, label, sub_label=None):
|
||||
Gtk.EventBox.__init__(self)
|
||||
|
||||
# cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
|
||||
# self.get_window().set_cursor(cursor)
|
||||
self._build_widgets(label, sub_label)
|
||||
|
||||
def _build_widgets(self, label, sub_label=None):
|
||||
container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
container.get_style_context().add_class("settings-box")
|
||||
|
||||
main_lbl = Gtk.Label()
|
||||
main_lbl.set_halign(Gtk.Align.START)
|
||||
main_lbl.get_style_context().add_class("settings-box-main-label")
|
||||
main_lbl.set_text(label)
|
||||
container.pack_start(main_lbl, True, True, 3)
|
||||
self.secondary_lbl = Gtk.Label()
|
||||
self.secondary_lbl.set_halign(Gtk.Align.START)
|
||||
self.secondary_lbl.get_style_context().add_class("settings-box-secondary-label")
|
||||
if sub_label:
|
||||
self.secondary_lbl.set_text(sub_label)
|
||||
else:
|
||||
self.secondary_lbl.set_text("")
|
||||
container.pack_start(self.secondary_lbl, True, True, 3)
|
||||
|
||||
self.add(container)
|
||||
|
||||
|
||||
class SwitchSettingsBox(Gtk.Box, GObject.GObject):
|
||||
__gsignals__ = {
|
||||
'changed': (GObject.SignalFlags.RUN_LAST, None, (bool,))
|
||||
}
|
||||
|
||||
def __init__(self, label, sub_label, schema):
|
||||
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
|
||||
GObject.GObject.__init__(self)
|
||||
self.switch = Gtk.Switch()
|
||||
self._schema = schema
|
||||
self._build_widgets(label, sub_label)
|
||||
|
||||
def _build_widgets(self, label, sub_label):
|
||||
self.get_style_context().add_class("settings-box")
|
||||
|
||||
self.switch.set_state(Settings.get_default().get_boolean(self._schema))
|
||||
self.switch.connect("state-set", self.__on_toggled)
|
||||
|
||||
label_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
main_lbl = Gtk.Label()
|
||||
main_lbl.set_halign(Gtk.Align.START)
|
||||
main_lbl.get_style_context().add_class("settings-box-main-label")
|
||||
main_lbl.set_text(label)
|
||||
label_container.pack_start(main_lbl, False, False, 3)
|
||||
secondary_lbl = Gtk.Label()
|
||||
secondary_lbl.set_halign(Gtk.Align.START)
|
||||
secondary_lbl.get_style_context().add_class("settings-box-secondary-label")
|
||||
secondary_lbl.set_text(sub_label)
|
||||
label_container.pack_start(secondary_lbl, False, False, 3)
|
||||
|
||||
self.pack_start(label_container, False, False, 0)
|
||||
|
||||
switch_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
switch_container.pack_start(self.switch, False, False, 0)
|
||||
switch_container.set_valign(Gtk.Align.CENTER)
|
||||
self.pack_end(switch_container, False, False, 0)
|
||||
|
||||
def __on_toggled(self, *_):
|
||||
Settings.get_default().set_boolean(self._schema, not self.switch.get_state())
|
||||
self.emit("changed", not self.switch.get_state())
|
||||
|
||||
|
||||
class SettingsBoxWithEntry(Gtk.Box):
|
||||
|
||||
def __init__(self, label, is_password=False):
|
||||
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.get_style_context().add_class("settings-box")
|
||||
self.entry = Gtk.Entry()
|
||||
if is_password:
|
||||
self.entry.set_visibility(False)
|
||||
self._build_widgets(label)
|
||||
|
||||
def _build_widgets(self, label):
|
||||
entry_label = Gtk.Label()
|
||||
entry_label.set_text(label)
|
||||
entry_label.get_style_context().add_class("settings-box-main-label")
|
||||
entry_label.set_halign(Gtk.Align.START)
|
||||
|
||||
self.pack_start(entry_label, True, True, 6)
|
||||
self.pack_end(self.entry, False, False, 6)
|
||||
|
||||
|
||||
class PasswordWindow(Gtk.Window):
|
||||
|
||||
def __init__(self):
|
||||
Gtk.Window.__init__(self)
|
||||
self.set_modal(True)
|
||||
self.set_size_request(500, 400)
|
||||
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
|
||||
self.resize(500, 400)
|
||||
self.set_resizable(False)
|
||||
self.set_border_width(36)
|
||||
self.old_password = None
|
||||
self._apply_btn = Gtk.Button()
|
||||
self._build_widgets()
|
||||
|
||||
def _build_widgets(self):
|
||||
header_bar = Gtk.HeaderBar()
|
||||
header_bar.set_title(_("Authentication Password"))
|
||||
header_bar.set_show_close_button(True)
|
||||
self.set_titlebar(header_bar)
|
||||
|
||||
self._apply_btn.set_label(_("Save"))
|
||||
self._apply_btn.connect("clicked", self.__on_apply_button_clicked)
|
||||
self._apply_btn.set_sensitive(False)
|
||||
self._apply_btn.get_style_context().add_class("suggested-action")
|
||||
|
||||
header_bar.pack_end(self._apply_btn)
|
||||
|
||||
container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
if Keyring.has_password():
|
||||
self.old_password = SettingsBoxWithEntry(_("Old Password"), True)
|
||||
self.old_password.entry.connect("changed", self._validate)
|
||||
container.pack_start(self.old_password, False, False, 6)
|
||||
|
||||
self.password = SettingsBoxWithEntry(_("Password"), True)
|
||||
self.password.entry.connect("changed", self._validate)
|
||||
|
||||
self.repeat_password = SettingsBoxWithEntry(_("Repeat Password"), True)
|
||||
self.repeat_password.entry.connect("changed", self._validate)
|
||||
|
||||
container.pack_start(self.password, False, False, 6)
|
||||
container.pack_start(self.repeat_password, False, False, 6)
|
||||
|
||||
self.add(container)
|
||||
|
||||
def _validate(self, *_):
|
||||
password = self.password.entry.get_text()
|
||||
repeat_password = self.repeat_password.entry.get_text()
|
||||
if not password:
|
||||
self.password.entry.get_style_context().add_class("error")
|
||||
valid_password = False
|
||||
else:
|
||||
self.password.entry.get_style_context().remove_class("error")
|
||||
valid_password = True
|
||||
|
||||
if not repeat_password or password != repeat_password:
|
||||
self.repeat_password.entry.get_style_context().add_class("error")
|
||||
valid_repeat_password = False
|
||||
else:
|
||||
self.repeat_password.entry.get_style_context().remove_class("error")
|
||||
valid_repeat_password = True
|
||||
|
||||
to_validate = [valid_password, valid_repeat_password]
|
||||
|
||||
if self.old_password:
|
||||
old_password = self.old_password.entry.get_text()
|
||||
if not old_password or old_password != Keyring.get_password():
|
||||
self.old_password.entry.get_style_context().add_class("error")
|
||||
valid_old_password = False
|
||||
else:
|
||||
self.old_password.entry.get_style_context().remove_class("error")
|
||||
valid_old_password = True
|
||||
to_validate.append(valid_old_password)
|
||||
|
||||
self._apply_btn.set_sensitive(all(to_validate))
|
||||
|
||||
def __on_apply_button_clicked(self, *_):
|
||||
if self._apply_btn.get_sensitive():
|
||||
password = self.password.entry.get_text()
|
||||
Keyring.set_password(password)
|
||||
self.destroy()
|
||||
class SettingsView:
|
||||
MAIN = 0
|
||||
PASSWORD = 1
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/com/github/bilelmoussaoui/Authenticator/settings.ui')
|
||||
class SettingsWindow(Gtk.Window):
|
||||
|
||||
__gtype_name__ = 'SettingsWindow'
|
||||
|
||||
lock_switch = Gtk.Template.Child()
|
||||
dark_theme_switch = Gtk.Template.Child()
|
||||
|
||||
headerbar = Gtk.Template.Child()
|
||||
|
||||
headerbar_stack = Gtk.Template.Child()
|
||||
main_stack = Gtk.Template.Child()
|
||||
|
||||
save_btn = Gtk.Template.Child()
|
||||
|
||||
password_entry = Gtk.Template.Child()
|
||||
repeat_password_entry = Gtk.Template.Child()
|
||||
|
||||
notification = Gtk.Template.Child()
|
||||
notification_label = Gtk.Template.Child()
|
||||
|
||||
view = GObject.Property(type=int)
|
||||
|
||||
def __init__(self):
|
||||
Gtk.Window.__init__(self)
|
||||
self.set_transient_for(Window.get_default())
|
||||
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
|
||||
self.set_size_request(600, 600)
|
||||
self.set_title(_("Settings"))
|
||||
self.resize(600, 600)
|
||||
super(SettingsWindow, self).__init__()
|
||||
self.init_template('SettingsWindow')
|
||||
|
||||
self.stack_switcher = Gtk.StackSwitcher()
|
||||
self.stack = Gtk.Stack()
|
||||
self.connect("notify::view", self.__update_view)
|
||||
|
||||
self._build_widgets()
|
||||
self.__init_widgets()
|
||||
|
||||
def _build_widgets(self):
|
||||
header_bar = Gtk.HeaderBar()
|
||||
header_bar.set_show_close_button(True)
|
||||
self.set_titlebar(header_bar)
|
||||
header_bar.set_custom_title(self.stack_switcher)
|
||||
self.stack_switcher.set_stack(self.stack)
|
||||
self.stack.get_style_context().add_class("settings-main-container")
|
||||
def __init_widgets(self):
|
||||
settings = Settings.get_default()
|
||||
settings.bind("night-mode", self.dark_theme_switch, "state", Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
appearance_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
dark_theme = SwitchSettingsBox(_("Dark theme"), _("Use a dark theme, if possible"), "night-mode")
|
||||
dark_theme.connect("changed", self.__on_dark_theme_changed)
|
||||
appearance_container.pack_start(dark_theme, False, False, 0)
|
||||
self.stack.add_titled(appearance_container, "appearance", _("Appearance"))
|
||||
self.lock_switch.set_active(Keyring.get_default().has_password())
|
||||
|
||||
behaviour_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
@Gtk.Template.Callback('lock_switch_state_changed')
|
||||
def __on_app_set_password(self, __, state):
|
||||
if state and not Keyring.get_default().has_password():
|
||||
self.props.view = SettingsView.PASSWORD
|
||||
else:
|
||||
Keyring.get_default().clear_password()
|
||||
self.__send_notification(_("Authentication password was unset. Please restart the application"))
|
||||
|
||||
clear_database = ClickableSettingsBox(_("Clear the database"), _("Erase existing accounts"))
|
||||
clear_database.connect("button-press-event", self.__on_clear_database_clicked)
|
||||
@Gtk.Template.Callback('save_btn_clicked')
|
||||
def __save_password(self, *__):
|
||||
if self.save_btn.get_sensitive():
|
||||
password = self.password_entry.get_text()
|
||||
Keyring.set_password(password)
|
||||
self.props.view = SettingsView.MAIN
|
||||
self.__send_notification(_("Authentication password is now enabled. Please restart the application."))
|
||||
|
||||
app_can_be_locked = SwitchSettingsBox(_("Lock the application"),
|
||||
_("Possibility to lock the application with a password"), "can-be-locked")
|
||||
app_can_be_locked.connect("changed", self.__on_app_can_be_locked_changed)
|
||||
|
||||
app_password = ClickableSettingsBox(_("Authentication password"),
|
||||
_("Set up application authentication password"))
|
||||
app_password.connect("button-press-event", self.__on_app_set_password)
|
||||
|
||||
behaviour_container.pack_start(clear_database, False, False, 0)
|
||||
behaviour_container.pack_start(app_can_be_locked, False, False, 0)
|
||||
behaviour_container.pack_start(app_password, False, False, 0)
|
||||
self.stack.add_titled(behaviour_container, "behaviour", _("Behaviour"))
|
||||
|
||||
self.add(self.stack)
|
||||
|
||||
def __on_app_can_be_locked_changed(self, __, state):
|
||||
"""notification = Gd.Notification()
|
||||
notification.set_timeout(5)
|
||||
|
||||
notification_lbl = Gtk.Label()
|
||||
notification_lbl.set_text(_("The application needs to be restarted first."))
|
||||
|
||||
notification.add(notification_lbl)
|
||||
notification_parent = self.stack.get_child_by_name("behaviour")
|
||||
notification_parent.add(notification)
|
||||
notification_parent.reorder_child(notification, 0)
|
||||
"""
|
||||
self.show_all()
|
||||
|
||||
if state and not Keyring.has_password():
|
||||
self.__on_app_set_password()
|
||||
|
||||
def __on_app_set_password(self, *_):
|
||||
password_window = PasswordWindow()
|
||||
password_window.set_transient_for(self)
|
||||
password_window.show_all()
|
||||
@Gtk.Template.Callback('back_btn_clicked')
|
||||
def __back_btn_clicked(self, *_):
|
||||
self.props.view = SettingsView.MAIN
|
||||
if not Keyring.get_default().has_password():
|
||||
self.lock_switch.set_active(False)
|
||||
|
||||
@Gtk.Template.Callback('dark_theme_switch_state_changed')
|
||||
@staticmethod
|
||||
def __on_dark_theme_changed(_, state):
|
||||
gtk_settings = Gtk.Settings.get_default()
|
||||
gtk_settings.set_property("gtk-application-prefer-dark-theme",
|
||||
state)
|
||||
|
||||
def __on_clear_database_clicked(self, *__):
|
||||
"""
|
||||
notification = Gd.Notification()
|
||||
notification.set_timeout(5)
|
||||
notification.connect("dismissed", self.__clear_database)
|
||||
container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
@Gtk.Template.Callback('password_entry_changed')
|
||||
def __validate_password(self, *_):
|
||||
password = self.password_entry.get_text()
|
||||
repeat_password = self.repeat_password_entry.get_text()
|
||||
if not password:
|
||||
self.password_entry.get_style_context().add_class("error")
|
||||
valid_password = False
|
||||
else:
|
||||
self.password_entry.get_style_context().remove_class("error")
|
||||
valid_password = True
|
||||
|
||||
notification_lbl = Gtk.Label()
|
||||
notification_lbl.set_text(_("The existing accounts will be erased in 5 seconds"))
|
||||
container.pack_start(notification_lbl, False, False, 3)
|
||||
if not repeat_password or password != repeat_password:
|
||||
self.repeat_password_entry.get_style_context().add_class("error")
|
||||
valid_repeat_password = False
|
||||
else:
|
||||
self.repeat_password_entry.get_style_context().remove_class("error")
|
||||
valid_repeat_password = True
|
||||
|
||||
undo_btn = Gtk.Button()
|
||||
undo_btn.set_label(_("Undo"))
|
||||
undo_btn.connect("clicked", lambda widget: notification.hide())
|
||||
container.pack_end(undo_btn, False, False, 3)
|
||||
to_validate = [valid_password, valid_repeat_password]
|
||||
|
||||
notification.add(container)
|
||||
notification_parent = self.stack.get_child_by_name("behaviour")
|
||||
notification_parent.add(notification)
|
||||
notification_parent.reorder_child(notification, 0)
|
||||
"""
|
||||
self.show_all()
|
||||
self.save_btn.set_sensitive(all(to_validate))
|
||||
|
||||
@staticmethod
|
||||
def __clear_database(*_):
|
||||
from ..models import Database, Keyring, AccountsManager
|
||||
from ..widgets.accounts import AccountsWidget
|
||||
Database.get_default().clear()
|
||||
Keyring.get_default().clear()
|
||||
AccountsManager.get_default().clear()
|
||||
AccountsWidget.get_default().clear()
|
||||
def __update_view(self, *_):
|
||||
if self.props.view == SettingsView.PASSWORD:
|
||||
self.main_stack.set_visible_child_name("password_view")
|
||||
self.headerbar_stack.set_visible_child_name("headerbar_password")
|
||||
self.headerbar.set_show_close_button(False)
|
||||
self.notification.set_reveal_child(False)
|
||||
self.notification_label.set_text("")
|
||||
else:
|
||||
self.main_stack.set_visible_child_name("settings_view")
|
||||
self.headerbar_stack.set_visible_child_name("headerbar_settings")
|
||||
self.headerbar.set_show_close_button(True)
|
||||
# Reset Password View
|
||||
# To avoid user saving a password he doesn't remember
|
||||
self.password_entry.set_text("")
|
||||
self.repeat_password_entry.set_text("")
|
||||
self.password_entry.get_style_context().remove_class("error")
|
||||
self.repeat_password_entry.get_style_context().remove_class("error")
|
||||
self.save_btn.set_sensitive(False)
|
||||
|
||||
def __send_notification(self, message):
|
||||
self.notification_label.set_text(message)
|
||||
self.notification.set_reveal_child(True)
|
||||
|
||||
GLib.timeout_add_seconds(5,
|
||||
lambda _: self.notification.set_reveal_child(False), None)
|
||||
|
|
Loading…
Add table
Reference in a new issue