Improve the way we handled some internals:

I always tied up widgets together in a stupid way.
This improves things a lot!
This commit is contained in:
Bilal Elmoussaoui 2019-02-14 21:51:39 +01:00
parent 97b5fd7de3
commit 3c085241d4
14 changed files with 307 additions and 248 deletions

View file

@ -15,6 +15,7 @@
<file compressed="true" preprocess="xml-stripblanks" alias="account_add.ui">ui/account_add.ui</file>
<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="accounts_widget.ui">ui/accounts_widget.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>
</gresource>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkImage" id="scan_img">
@ -11,12 +11,10 @@
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">350</property>
<property name="default_height">500</property>
<child>
<placeholder/>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
@ -64,5 +62,8 @@
</child>
</object>
</child>
<child>
<placeholder/>
</child>
</template>
</interface>

View file

@ -141,10 +141,8 @@
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="model">providers_store</property>
<property name="active">0</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">0</property>
<signal name="changed" handler="provider_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="provider_entry">

View file

@ -1,17 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<template class="EditAccountWindow" parent="GtkWindow">
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">350</property>
<property name="default_height">500</property>
<child>
<placeholder/>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
@ -43,5 +41,8 @@
</child>
</object>
</child>
<child>
<placeholder/>
</child>
</template>
</interface>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkImage" id="copy_img">
@ -20,6 +20,10 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="text" translatable="yes">Edit</property>
<signal name="clicked" handler="edit_btn_clicked" swapped="no"/>
</object>
@ -34,6 +38,10 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="text" translatable="yes">Delete</property>
</object>
<packing>

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<template class="AccountsWidget" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkProgressBar" id="otp_progress_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="progress-bar"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="HdyColumn">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="maximum_width">700</property>
<child>
<object class="GtkBox" id="accounts_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="accounts-widget"/>
</style>
</template>
</interface>

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkImage" id="previous_img">
<property name="visible">True</property>
<property name="can_focus">False</property>
@ -10,22 +11,76 @@
<template class="SettingsWindow" parent="GtkWindow">
<property name="can_focus">False</property>
<property name="type">popup</property>
<property name="modal">True</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>
<signal name="delete-event" handler="settings_window_deleted" swapped="no"/>
<child type="titlebar">
<object class="GtkStack" id="headerbar_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">slide-left-right</property>
<child>
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Preferences</property>
<property name="show_close_button">True</property>
</object>
<packing>
<property name="name">headerbar_main</property>
</packing>
</child>
<child>
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<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>
</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="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>
<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">
<object class="GtkOverlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkOverlay">
<object class="GtkRevealer" id="notification">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
@ -36,11 +91,11 @@
<class name="app-notification"/>
</style>
</object>
<packing>
<property name="index">-1</property>
</packing>
</child>
</object>
<packing>
<property name="index">-1</property>
</packing>
</child>
</object>
<packing>
@ -53,198 +108,205 @@
<object class="GtkStack" id="main_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">36</property>
<property name="border_width">32</property>
<property name="transition_type">slide-left-right</property>
<child>
<object class="GtkBox">
<object class="HdyColumn">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="maximum_width">700</property>
<child>
<object class="GtkLabel">
<object class="GtkBox">
<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>
<property name="orientation">vertical</property>
<child>
<object class="GtkListBoxRow">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">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="GtkBox">
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</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">
<object class="GtkBox">
<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>
<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="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<object class="GtkSwitch" id="dark_theme_switch">
<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>
<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="padding">6</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="settings-box"/>
</style>
</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"/>
<class name="settings-row"/>
</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">
<object class="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</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">
<object class="GtkBox">
<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>
<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="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<object class="GtkSwitch" id="lock_switch">
<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>
<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="padding">6</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="settings-box"/>
</style>
</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"/>
<class name="settings-row"/>
</style>
</object>
</child>
<style>
<class name="settings-row"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</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>
<packing>
@ -395,59 +457,5 @@
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkStack" id="headerbar_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">slide-left-right</property>
<child>
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Preferences</property>
<property name="show_close_button">True</property>
</object>
<packing>
<property name="name">headerbar_main</property>
</packing>
</child>
<child>
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<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>
</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="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>
</template>
</interface>

View file

@ -84,33 +84,7 @@
</packing>
</child>
<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">1</property>
</packing>
<placeholder/>
</child>
<child>
<object class="GtkScrolledWindow" id="accounts_scrolled_window">

View file

@ -139,3 +139,4 @@ class Keyring:
def clear_password():
schema = Keyring.get_default().password_schema
Secret.password_clear_sync(schema, {}, None)

View file

@ -25,6 +25,7 @@ from Authenticator.models import Account, AccountsManager, ProviderManager, Favi
from Authenticator.utils import load_pixbuf_from_provider
@Gtk.Template(resource_path='/com/github/bilelmoussaoui/Authenticator/accounts_widget.ui')
class AccountsWidget(Gtk.Box, GObject.GObject):
instance = None
@ -33,32 +34,29 @@ class AccountsWidget(Gtk.Box, GObject.GObject):
'account-added': (GObject.SignalFlags.RUN_LAST, None, ()),
}
__gtype_name__ = 'AccountsWidget'
accounts_container = Gtk.Template.Child()
otp_progress_bar = Gtk.Template.Child()
def __init__(self):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
super(AccountsWidget, self).__init__()
GObject.GObject.__init__(self)
self.get_style_context().add_class("accounts-widget")
self.init_template('AccountsWidget')
self._providers = {}
self._to_delete = []
self._build_widgets()
self.__fill_data()
self.__init_widgets()
def _build_widgets(self):
self.otp_progress_bar = Gtk.ProgressBar()
self.otp_progress_bar.get_style_context().add_class("progress-bar")
self.add(self.otp_progress_bar)
AccountsManager.get_default().connect("counter_updated",
self._on_counter_updated)
self.accounts_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
def __init_widgets(self):
accounts_manager = AccountsManager.get_default()
accounts_manager.connect("counter_updated",
self._on_counter_updated)
# Add different accounts to the main view
for account in accounts_manager.accounts:
self.append(account)
self.accounts_column = Handy.Column()
self.accounts_column.set_maximum_width(700)
self.accounts_column.add(self.accounts_container)
accounts_scrolled = Gtk.ScrolledWindow()
accounts_scrolled.add_with_viewport(self.accounts_column)
self.pack_start(accounts_scrolled, True, True, 0)
@staticmethod
def get_default():
@ -107,12 +105,6 @@ class AccountsWidget(Gtk.Box, GObject.GObject):
self._reorder()
self._clean_unneeded_providers_widgets()
def __fill_data(self):
"""Fill the Accounts List with accounts."""
accounts = AccountsManager.get_default().accounts
for account in accounts:
self.append(account)
def _on_account_deleted(self, account_list):
if len(account_list.get_children()) == 0:
self._to_delete.append(account_list)

View file

@ -33,6 +33,11 @@ class AccountRow(Gtk.ListBoxRow, GObject.GObject):
"""
__gtype_name__ = 'AccountRow'
__gsignals__ = {
'pin-copied': (GObject.SignalFlags.RUN_LAST, None, (str,)),
'account-updated': (GObject.SignalFlags.RUN_LAST, None, (str,)),
}
account_name_label = Gtk.Template.Child()
pin_label = Gtk.Template.Child()
@ -74,12 +79,14 @@ class AccountRow(Gtk.ListBoxRow, GObject.GObject):
self.pin_label.set_tooltip_text(_("Couldn't generate the secret code"))
@Gtk.Template.Callback('copy_btn_clicked')
def _on_copy(self, *_):
def _on_copy(self, *__):
"""
Copy button clicked signal handler.
Copies the OTP pin to the clipboard
"""
self._account.copy_pin()
self.emit("pin-copied",
_("The PIN of {} was copied to the clipboard").format(self.account.username))
@Gtk.Template.Callback('edit_btn_clicked')
def _on_edit(self, *_):
@ -94,7 +101,7 @@ class AccountRow(Gtk.ListBoxRow, GObject.GObject):
edit_window.show_all()
edit_window.present()
def _on_update(self, _, account_name, provider):
def _on_update(self, __, account_name, provider):
"""
On account update signal handler.
Updates the account name and provider
@ -107,6 +114,8 @@ class AccountRow(Gtk.ListBoxRow, GObject.GObject):
"""
self.account_name_label.set_text(account_name)
self.account.update(account_name, provider)
self.emit("account-updated",
_("The account was updated successfully"))
def _on_pin_updated(self, _, pin):
"""

View file

@ -62,6 +62,9 @@ class SettingsWindow(Gtk.Window):
@Gtk.Template.Callback('lock_switch_state_changed')
def __on_app_set_password(self, __, state):
# TODO: the state of the lock switch is set
# When the window is open for the first time
# The notification is then shown the user which is not great :/
if state and not Keyring.get_default().has_password():
self.props.view = SettingsView.PASSWORD
elif Keyring.get_default().has_password():
@ -130,5 +133,5 @@ class SettingsWindow(Gtk.Window):
self.notification_label.set_text(message)
self.notification.set_reveal_child(True)
GLib.timeout_add_seconds(3,
GLib.timeout_add_seconds(5,
lambda _: self.notification.set_reveal_child(False), None)

View file

@ -50,9 +50,6 @@ class Window(Gtk.ApplicationWindow, GObject.GObject):
search_bar = Gtk.Template.Child()
notification = Gtk.Template.Child()
notification_label = Gtk.Template.Child()
accounts_viewport = Gtk.Template.Child()
password_entry = Gtk.Template.Child()

View file

@ -30,7 +30,7 @@ require_version('Gtk', '3.0')
require_version('Gdk', '3.0')
require_version("Handy", "0.0")
require_version('Secret', '1')
from gi.repository import Gio
from gi.repository import Gio, Handy
sys.path.insert(1, '@PYTHON_EXEC_DIR@')
sys.path.insert(1, '@PYTHON_DIR@')
@ -68,6 +68,7 @@ if __name__ == "__main__":
sys.exit("Version : @VERSION@")
else:
try:
Handy.init(None)
from Authenticator.application import Application
app = Application.get_default()
Application.IS_DEVEL = "@PROFILE@" == 'Devel'