Ejemplo n.º 1
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        Handy.init()
        actions = [{
            'name': 'settings',
            'func': self.show_settings_window,
            'accel': '<Primary>comma'
        }, {
            'name': 'about',
            'func': self.show_about_dialog
        }, {
            'name': 'logout',
            'func': self.log_out
        }, {
            'name': 'search-guilds',
            'func': self.search_guilds,
            'accel': '<Primary>k'
        }]

        for a in actions:
            c_action = Gio.SimpleAction.new(a['name'], None)
            c_action.connect('activate', a['func'])
            self.add_action(c_action)
            if 'accel' in a.keys():
                self.set_accels_for_action(f'app.{a["name"]}', [a['accel']])
Ejemplo n.º 2
0
def main(version):

    Handy.init()

    app = Application()
    app.version = version
    return app.run(sys.argv)
Ejemplo n.º 3
0
    def do_startup(self):
        Gtk.Application.do_startup(self)

        GLib.set_application_name(_('Komikku'))
        GLib.set_prgname(self.application_id)

        Handy.init()
        Notify.init(_('Komikku'))
Ejemplo n.º 4
0
    def do_startup(self):
        # Startup application
        Gtk.Application.do_startup(self)
        self.setup_actions()
        self.load_css()

        # Init Handy
        Handy.init()
Ejemplo n.º 5
0
    def _setup(self):
        Handy.init()

        self._popup = None
        self._worker = None
        self._busy = False
        self._editing = False
        self._to_copy = []
        self._to_cut = []
        self._last_clicked = None
        self._dont_activate = False
        self._force_select = False
        self._history = []
        self._index = -1
        self._search_delay_handler_id = 0

        self.gesture = Gtk.GestureLongPress.new(self.treeview)
        self.gesture.connect("pressed", self._on_long_pressed)

        self.filtered.set_visible_func(self._filter, data=None)
        self.sorted.set_default_sort_func(self._sort, None)
        self.selection.connect("changed", self._on_selection_changed)
        self.selection.set_select_function(self._on_select)
        self.treeview.connect("row-activated", self._on_row_activated)
        self.treeview.connect("button-press-event", self._on_clicked)

        self.name_cell.connect("editing-started", self._on_rename_started)
        self.name_cell.connect("editing-canceled", self._on_rename_finished)
        self.name_cell.connect("edited", self._on_rename_updated)

        self.previous.connect("clicked", self._on_go_previous)
        self.next.connect("clicked", self._on_go_next)
        self.rename.connect("clicked", self._on_rename_clicked)
        self.delete.connect("clicked", self._on_delete_clicked)
        self.cut.connect("clicked", self._on_cut_clicked)
        self.copy.connect("clicked", self._on_copy_clicked)
        self.paste.connect("clicked", self._on_paste_clicked)
        self.select_all.connect("clicked", self._on_select_all)
        self.select_none.connect("clicked", self._on_select_none)
        self.new_folder.connect("clicked", self._on_new_folder)
        self.close_button.connect("clicked", self._on_button_closed)
        self.help_button.connect("clicked", self._on_help_clicked)
        self.about_button.connect("clicked", self._on_about_clicked)
        self.show_hidden_button.connect("toggled", self._on_hidden_toggled)
        self.a_to_z_button.connect("toggled", self._on_sort_toggled)

        self.search.connect("toggled", self._on_search_toggled)
        self.search_entry.connect("search-changed", self._on_search_changed)
        self.search_entry.connect("stop-search", self._on_search_stopped)
        self.back.connect("clicked", self._on_back_clicked)

        places = PortfolioPlaces()
        places.connect("updated", self._on_places_updated)
        places.connect("removed", self._on_places_removed)
        self.places_box.add(places)

        self._move(PortfolioPlaces.PORTFOLIO_HOME_DIR)
Ejemplo n.º 6
0
 def do_startup(self):
     log.info(distro.linux_distribution(full_distribution_name=False))
     log.info("Starting up cozy " + __version__)
     self.ui = CozyUI(self.pkgdatadir, self, __version__)
     init_db()
     Gtk.Application.do_startup(self)
     Handy.init()
     log.info("libhandy version: {}".format(Handy._version))
     self.ui.startup()
Ejemplo n.º 7
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        Handy.init()

        action = Gio.SimpleAction.new("quit", None)
        action.connect("activate", self.do_quit)
        self.add_action(action)

        self.set_accels_for_action("app.quit", ["<Ctl>q"])
Ejemplo n.º 8
0
 def do_startup(self):
     Handy.init()
     Gtk.Application.do_startup(self)
     self.setup_actions()
     self.build_gstreamer_pipeline()
     devmonitor = Gst.DeviceMonitor.new()
     devmonitor.add_filter('Video/Source', Gst.Caps.from_string('video/x-raw'))
     logger.debug('Monitor: {}', devmonitor)
     self.devmonitor = devmonitor
     NM.Client.new_async(None, self.cb_networkmanager_client_init_done)
Ejemplo n.º 9
0
def init():
    print("initializing")
    Gtk.init()
    Handy.init()
    global builder
    builder = Gtk.Builder()
    builder.add_from_file("/app/bin/app.ui")
    builder.connect_signals(Handler())
    global objects
    objects = builder.get_objects()
    o("window").show_all()
    print("initialized")
Ejemplo n.º 10
0
    def do_startup(self):
        Gtk.Application.do_startup(self)

        css_provider = Gtk.CssProvider()
        css_provider.load_from_resource(f"{Constants.RESOURCEID}/ui/style.css")
        screen = Gdk.Screen.get_default()
        Gtk.StyleContext.add_provider_for_screen(
            screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )

        self.setup_actions()

        Handy.init()
Ejemplo n.º 11
0
    def do_startup(self):
        if os.path.isdir('/var/cache/files') is False:
            os.mkdir('/var/cache/files')
            os.mkdir('/var/cache/files/covers')

        Gtk.Application.do_startup(self)
        Handy.init()

        action = Gio.SimpleAction.new("quit", None)
        action.connect("activate", self.do_quit)
        self.add_action(action)

        self.set_accels_for_action("app.quit", ["<Ctl>q"])
Ejemplo n.º 12
0
    def do_startup(self):
        Gtk.Application.do_startup(self)

        Handy.init()

        # Load CSS
        css_provider = Gtk.CssProvider()
        css_provider.load_from_resource(
            '/com/rafaelmardojai/WebfontKitGenerator/css/styles.css')
        screen = Gdk.Screen.get_default()
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, css_provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)
Ejemplo n.º 13
0
    def __init__(self, version: str = None):
        super().__init__(application_id=APP_ID,
                         flags=Gio.ApplicationFlags.HANDLES_OPEN | Gio.ApplicationFlags.HANDLES_COMMAND_LINE)

        Handy.init()

        self.add_main_option('new', 110, GLib.OptionFlags.OPTIONAL_ARG, GLib.OptionArg.STRING,
                             _('Open new document on start.'))

        self.version = version

        # Init GSettings
        self.settings = Settings.new()

        self.init_style()
        self.window: NorkaWindow = None

        # Init storage location and SQL structure
        self.base_path = os.path.join(GLib.get_user_data_dir(), APP_TITLE)
        storage_path = self.settings.get_string("storage-path")
        if not storage_path:
            storage_path = os.path.join(self.base_path, STORAGE_NAME)
            self.settings.set_string("storage-path", storage_path)

        self.storage = Storage(storage_path)
        try:
            self.storage.init()
        except Exception as e:
            sys.exit(e)

        quit_action = Gio.SimpleAction.new("quit", None)
        quit_action.connect("activate", self.on_quit)
        self.add_action(quit_action)
        self.set_accels_for_action('app.quit', ('<Control>q',))

        about_action = Gio.SimpleAction.new("about", None)
        about_action.connect("activate", self.on_about)
        self.add_action(about_action)

        preferences_action = Gio.SimpleAction.new("preferences", None)
        preferences_action.connect("activate", self.on_preferences)
        self.add_action(preferences_action)
        self.set_accels_for_action('app.preferences', ('<Control>comma',))

        shortcuts_action = Gio.SimpleAction.new("shortcuts", None)
        shortcuts_action.connect("activate", self.on_shortcuts)
        self.add_action(shortcuts_action)

        format_shortcuts_action = Gio.SimpleAction.new("format_shortcuts", None)
        format_shortcuts_action.connect("activate", self.on_format_shortcuts)
        self.add_action(format_shortcuts_action)
Ejemplo n.º 14
0
 def do_startup(self):
     """
         Init application
     """
     Gtk.Application.do_startup(self)
     Handy.init()
     if self.__window is None:
         from lollypop.window import Window
         self.init()
         self.__window = Window()
         self.__window.connect("delete-event", self.__hide_on_delete)
         self.__window.setup()
         self.__window.show()
         self.player.restore_state()
Ejemplo n.º 15
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        Handy.init()

        self._style_manager = Handy.StyleManager.get_default()
        if settings.get_int('theme') == 0:
            self._style_manager.set_color_scheme(Handy.ColorScheme.FORCE_LIGHT)
        elif settings.get_int('theme') == 1:
            self._style_manager.set_color_scheme(Handy.ColorScheme.FORCE_DARK)
        elif settings.get_int('theme') == 2:
            self._style_manager.set_color_scheme(Handy.ColorScheme.FORCE_LIGHT)
        elif settings.get_int('theme') == 3:
            self._style_manager.set_color_scheme(
                Handy.ColorScheme.PREFER_LIGHT)

        action = Gio.SimpleAction.new('prefs', None)
        action.connect('activate', self._prefs_cb)
        self.add_action(action)
        self.set_accels_for_action('app.prefs', ('<Ctrl>E', ))

        action = Gio.SimpleAction.new('theme_system', None)
        action.connect('activate', self._theme_system)
        self.add_action(action)

        action = Gio.SimpleAction.new('theme_light', None)
        action.connect('activate', self._theme_light)
        self.add_action(action)

        action = Gio.SimpleAction.new('theme_sepia', None)
        action.connect('activate', self._theme_sepia)
        self.add_action(action)

        action = Gio.SimpleAction.new('theme_dark', None)
        action.connect('activate', self._theme_dark)
        self.add_action(action)

        action = Gio.SimpleAction.new('shortcuts', None)
        action.connect('activate', self._shortcuts_cb)
        self.add_action(action)
        self.set_accels_for_action('app.shortcuts', ('<Ctrl>question', ))

        action = Gio.SimpleAction.new('about', None)
        action.connect('activate', self._about_cb)
        self.add_action(action)

        action = Gio.SimpleAction.new('quit', None)
        action.connect('activate', self._quit_cb)
        self.add_action(action)
        self.set_accels_for_action('app.quit', ('<Ctrl>Q', ))
Ejemplo n.º 16
0
    def __init__(self, application_id, *args, **kwargs):
        super().__init__(*args,
                         application_id=application_id,
                         flags=Gio.ApplicationFlags.HANDLES_OPEN,
                         **kwargs)

        self.add_main_option("verbose", b"v", GLib.OptionFlags.NONE,
                             GLib.OptionArg.NONE, "Verbose output", None)

        Handy.init()

        self.window = None
        self.settings = Settings.new()
        self.inhibitor = None
        self._application_id = application_id
Ejemplo n.º 17
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        GLib.set_application_name(_('Dialect'))
        GLib.set_prgname('com.github.gi_lom.dialect')
        self.setup_actions()

        Handy.init()  # Init Handy
        Gst.init(None)  # Init Gst

        # Load CSS
        css_provider = Gtk.CssProvider()
        css_provider.load_from_resource(f'{RES_PATH}/style.css')
        screen = Gdk.Screen.get_default()
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
Ejemplo n.º 18
0
class HelloWindow(Handy.ApplicationWindow):
    __gtype_name__ = 'HelloWindow'

    Handy.init()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        header = Handy.HeaderBar()
        header.props.show_close_button = True
        header.props.hexpand = True
        header.props.title = "Hello World"

        label = Gtk.Label("Hello World")
        label.props.expand = True
        label.props.valign = label.props.halign = Gtk.Align.CENTER

        grid = Gtk.Grid()
        grid.props.expand = True
        grid.attach(header, 0, 0, 1, 1)
        grid.attach(label, 0, 1, 1, 1)

        self.add(grid)
        self.props.default_width = 480
        self.props.default_height = 320
        self.show_all()
Ejemplo n.º 19
0
Archivo: main.py Proyecto: Mu-L/Kooha
    def do_startup(self):
        Gtk.Application.do_startup(self)

        css_provider = Gtk.CssProvider()
        css_provider.load_from_resource('/io/github/seadve/Kooha/style.css')
        screen = Gdk.Screen.get_default()
        Gtk.StyleContext.add_provider_for_screen(
            screen,
            css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )

        self.settings = Gio.Settings.new('io.github.seadve.Kooha')
        self.setup_actions()

        Handy.init()
Ejemplo n.º 20
0
    def do_startup(self):
        Gtk.Application.do_startup(self)

        Handy.init()

        css_provider = Gtk.CssProvider()
        css_provider.load_from_resource('/io/github/seadve/Kooha/style.css')
        screen = Gdk.Screen.get_default()
        Gtk.StyleContext.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

        self.settings = Gio.Settings.new('io.github.seadve.Kooha')

        self.setup_actions()
        self.set_accels_for_action("app.show-shortcuts", ["<Ctrl>question"])
        self.set_accels_for_action("app.change-capture-mode", ["<Ctrl>f"])
        self.set_accels_for_action("app.quit", ["<Ctrl>q"])
Ejemplo n.º 21
0
 def do_startup(self):
     Gtk.Application.do_startup(self)
     Handy.init()
     self.settings = Gio.Settings.new(self.props.application_id)
     self.settings.bind('dark-mode', Gtk.Settings.get_default(),
                        'gtk-application-prefer-dark-theme',
                        Gio.SettingsBindFlags.DEFAULT)
     # Setup actions
     new_window_action = Gio.SimpleAction.new(
         'new-window', GLib.VariantType('s'))
     new_window_action.connect(
         'activate', lambda _, param: self._new_window(param.get_string()))
     self.add_action(new_window_action)
     # Setup CSS
     css_uri = 'resource:///com/github/unrud/VideoDownloader/style.css'
     css_provider = Gtk.CssProvider()
     css_provider.load_from_file(Gio.File.new_for_uri(css_uri))
     Gtk.StyleContext.add_provider_for_screen(
         Gdk.Screen.get_default(), css_provider,
         Gtk.STYLE_PROVIDER_PRIORITY_USER)
Ejemplo n.º 22
0
  def do_startup(self):
    Gtk.Application.do_startup(self)

    Handy.init()

    web_context = WebKit2.WebContext.get_default()
    web_context.set_cache_model(WebKit2.CacheModel.WEB_BROWSER)
    cookies_file_path = GLib.get_user_data_dir() + '/cookies'
    cookie_manager = WebKit2.WebContext.get_cookie_manager(web_context)
    cookie_manager.set_accept_policy(WebKit2.CookieAcceptPolicy.ALWAYS)
    cookie_manager.set_persistent_storage(cookies_file_path, WebKit2.CookiePersistentStorage.TEXT)

    actions = [ ('prefs', self._prefs_cb, ('<Ctrl>E',)),
                ('shortcuts', self._shortcuts_cb, ('<Ctrl>F1',)),
                ('about', self._about_cb, None) ]

    for action, callback, accel in actions:
      simple_action = Gio.SimpleAction.new(action, None)
      simple_action.connect('activate', callback)
      self.add_action(simple_action)
      if accel: self.set_accels_for_action('app.' + action, accel)
Ejemplo n.º 23
0
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

import gi

gi.require_version("Handy", "1")
gi.require_version("Gtk", "3.0")
gi.require_version("WebKit2", "4.0")
from gi.repository import Gtk, GLib, Gdk, WebKit2, GdkPixbuf, Gio, Handy

from hn.api import top_stories, get_comment, get_story, Comment, Story
from hn.bus import Bus

BG_TASKS = ThreadPoolExecutor(max_workers=4)
WEBEXT_DIR = '/home/david/git/webkit-webextension'
Handy.init(
)  # Must call this otherwise the Template() calls don't know how to resolve any Hdy* widgets


def load_icon_to_pixbuf(name, width):
    path = f'/hn/icons/{name}'
    pixbuf = GdkPixbuf.Pixbuf.new_from_resource_at_scale(path, width, -1, True)
    return pixbuf


data = pkg_resources.resource_stream('hn', 'resources')
glib_data = GLib.Bytes.new(data.read())
resource = Gio.Resource.new_from_data(glib_data)
resource._register()
_rs = Gio.resources_lookup_data('/hn/css/reader_mode.css',
                                Gio.ResourceLookupFlags.NONE)
READER_CSS = _rs.get_data().decode().replace('\n', '')
Ejemplo n.º 24
0
class BottlesListEntry(Handy.ActionRow):
    __gtype_name__ = 'BottlesListEntry'

    Handy.init()
    '''Get widgets from template'''
    btn_details = Gtk.Template.Child()
    btn_delete = Gtk.Template.Child()
    btn_browse = Gtk.Template.Child()
    btn_run = Gtk.Template.Child()
    btn_upgrade = Gtk.Template.Child()
    btn_repair = Gtk.Template.Child()
    btn_programs = Gtk.Template.Child()
    btn_run_executable = Gtk.Template.Child()
    label_environment = Gtk.Template.Child()
    label_state = Gtk.Template.Child()
    icon_damaged = Gtk.Template.Child()
    grid_versioning = Gtk.Template.Child()

    def __init__(self, window, configuration, arg_executable, **kwargs):
        super().__init__(**kwargs)
        '''Init template'''
        self.init_template()
        '''Common variables'''
        self.window = window
        self.runner = window.runner
        self.configuration = configuration[1]
        self.label_environment_context = self.label_environment.get_style_context(
        )
        self.arg_executable = arg_executable
        '''Check runner type by name'''
        if self.configuration.get("Runner").startswith("lutris"):
            self.runner_type = "wine"
        else:
            self.runner_type = "proton"
        '''Signal connections'''
        self.btn_details.connect('pressed', self.show_details)
        self.btn_details.connect('activate', self.show_details)
        self.btn_delete.connect('pressed', self.confirm_delete)
        self.btn_upgrade.connect('pressed', self.upgrade_runner)
        self.btn_run.connect('pressed', self.run_executable)
        self.btn_browse.connect('pressed', self.run_browse)
        self.btn_repair.connect('pressed', self.repair)
        self.btn_run_executable.connect('pressed', self.run_executable)
        '''Populate widgets'''
        self.grid_versioning.set_visible(self.configuration.get("Versioning"))
        self.label_state.set_text(str(self.configuration.get("State")))
        self.set_title(self.configuration.get("Name"))
        self.label_environment.set_text(self.configuration.get("Environment"))
        self.label_environment_context.add_class(
            "tag-%s" % self.configuration.get("Environment").lower())
        '''Toggle btn_upgrade
        if self.configuration.get("Runner") != self.runner.get_latest_runner(self.runner_type):
            self.btn_upgrade.set_visible(True)
        '''
        '''If configuration is broken'''
        if self.configuration.get("Broken"):
            for w in [self.btn_repair, self.icon_damaged]:
                w.set_visible(True)

            for w in [
                    self.btn_details, self.btn_upgrade, self.btn_run,
                    self.btn_browse, self.btn_programs
            ]:
                w.set_sensitive(False)
        else:
            '''Check for arguments from configuration'''
            if self.arg_executable:
                logging.info(
                    _("Arguments found for executable: [{executable}].").
                    format(executable=self.arg_executable))

                for w in [
                        self.btn_details, self.btn_upgrade, self.btn_run,
                        self.btn_browse, self.btn_programs, self.btn_delete
                ]:
                    w.set_visible(False)
                self.btn_run_executable.set_visible(True)

    '''Repair bottle'''

    def repair(self, widget):
        self.runner.repair_bottle(self.configuration)

    '''Display file dialog for executable'''

    def run_executable(self, widget):
        if not self.arg_executable:
            '''If executable is not Bottles argument'''
            file_dialog = Gtk.FileChooserDialog(
                _("Choose a Windows executable file"), self.window,
                Gtk.FileChooserAction.OPEN,
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN,
                 Gtk.ResponseType.OK))
            '''Create filters for allowed extensions'''
            filter_exe = Gtk.FileFilter()
            filter_exe.set_name(".exe")
            filter_exe.add_pattern("*.exe")

            filter_msi = Gtk.FileFilter()
            filter_msi.set_name(".msi")
            filter_msi.add_pattern("*.msi")

            filter_bat = Gtk.FileFilter()
            filter_bat.set_name(".bat")
            filter_bat.add_pattern("*.bat")

            file_dialog.add_filter(filter_exe)
            file_dialog.add_filter(filter_msi)
            file_dialog.add_filter(filter_bat)

            response = file_dialog.run()

            if response == Gtk.ResponseType.OK:
                self.runner.run_executable(self.configuration,
                                           file_dialog.get_filename())

            file_dialog.destroy()
        else:
            '''Use executable provided as bottles argument'''
            self.runner.run_executable(self.configuration, self.arg_executable)
            self.arg_executable = False
            self.runner.update_bottles()

    '''Browse bottle drive_c files'''

    def run_browse(self, widget):
        self.runner.open_filemanager(self.configuration)

    '''Show dialog to confirm runner upgrade'''

    def upgrade_runner(self, widget):
        dialog_upgrade = BottlesMessageDialog(
            parent=self.window,
            title=_("Confirm upgrade"),
            message=_("This will change the runner from {0} to {1}.").format(
                self.configuration.get("Runner"),
                self.runner.get_latest_runner(self.runner_type)))
        response = dialog_upgrade.run()

        if response == Gtk.ResponseType.OK:
            self.runner.update_configuration(self.configuration, "Runner",
                                             self.runner.get_latest_runner())
            self.btn_upgrade.set_visible(False)

        dialog_upgrade.destroy()

    '''Show details page'''

    def show_details(self, widget):
        self.window.show_details_view(configuration=self.configuration)

    '''Show dialog to confirm bottle deletion'''

    def confirm_delete(self, widget):
        dialog_delete = BottlesMessageDialog(
            parent=self.window,
            title=_("Confirm deletion"),
            message=_(
                "Are you sure you want to delete this Bottle and all files?"))
        response = dialog_delete.run()

        if response == Gtk.ResponseType.OK:
            self.runner.delete_bottle(self.configuration)
            self.destroy()

        dialog_delete.destroy()
Ejemplo n.º 25
0
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later

from gi.repository import Gtk, Handy
from .shalatlistrow import ShalatListRow
Handy.init()


@Gtk.Template(resource_path='/com/github/yursan9/Arkan/ui/shalatlist.ui')
class ShalatList(Handy.Column):
    __gtype_name__ = 'ShalatList'

    listbox = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.listbox.set_header_func(self._add_separator)

    def populate(self, data):
        self.listbox.foreach(lambda widget: widget.destroy())
Ejemplo n.º 26
0
class MainWindow(Handy.ApplicationWindow):
    __gtype_name__ = 'MainWindow'

    __gsignals__ = {
        'notify-requested': (GObject.SIGNAL_RUN_CLEANUP, None, (str, ))
    }

    Handy.init()

    main_container = Gtk.Template.Child()
    main_paned = Gtk.Template.Child()
    main_overlay = Gtk.Template.Child()
    button_next_page = Gtk.Template.Child()
    button_previous_page = Gtk.Template.Child()

    status_loading = Gtk.Template.Child()
    loading_spinner = Gtk.Template.Child()
    loading_message = Gtk.Template.Child()
    revealer_notification = Gtk.Template.Child()
    notification_icon = Gtk.Template.Child()
    notification_message = Gtk.Template.Child()

    # To remember the previous value of application variables for deciding
    # which child widget to reload
    tarajem_visibility: bool = False
    surah_number: int = None
    ayah_number: int = None
    page_number: int = None
    page_focused: int = None
    tarajem_names: list = None

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)

        # Set the window application name identifier, so it can be recognized
        # by the user in the desktop application switcher
        self.set_title(const.APPLICATION_NAME)
        self.set_wmclass(const.APPLICATION_NAME, const.APPLICATION_NAME)

        # FIXME: the application icon appears too small
        self.set_default_icon_name(const.APPLICATION_ID)

        self.setup_headerbar()
        self.setup_musshaf_viewer()
        self.setup_tarajem_viewer()

        self.show_all()

        self.setup_window_size()

        # Init self variables
        self.surah_number = glob.surah_number
        self.ayah_number = glob.ayah_number

        # Init children states
        self.headerbar.popover_nav.update()
        self.headerbar.popover_nav_alt.update()
        self.musshaf_viewer_right.update()
        self.musshaf_viewer_left.update()
        self.headerbar.popover_tarajem.populate()
        self.headerbar.popover_telaawa.populate()
        self.headerbar.popover_listofcontents.populate()

        self.headerbar.button_open_tarajem.set_active(glob.tarajem_visibility)

    def setup_headerbar(self) -> None:
        self.headerbar = HeaderBar()
        self.main_container.pack_start(self.headerbar, False, True, 0)

        self.headerbar.connect('tarajem-toggled', self.reload_tarajem_viewer)
        self.headerbar.connect('mobileview-toggled',
                               self.reload_navigation_panel)

        self.headerbar.popover_bookmark.connect(
            'go-to-page', self.headerbar.popover_nav.go_to_defined_page)
        self.headerbar.popover_bookmark.connect(
            'go-to-page', self.headerbar.popover_nav_alt.go_to_defined_page)

        self.headerbar.popover_search.connect(
            'go-to-suraya', self.headerbar.popover_nav.go_to_suraya)
        self.headerbar.popover_search.connect(
            'go-to-suraya', self.headerbar.popover_nav_alt.go_to_suraya)

        self.headerbar.popover_tarajem.connect('tarajem-names-updated',
                                               self.reload_tarajem_viewer)
        self.headerbar.popover_telaawa.connect(
            'go-to-next-ayah', self.headerbar.popover_nav.go_to_next_ayah)
        self.headerbar.popover_telaawa.connect(
            'go-to-previous-ayah',
            self.headerbar.popover_nav.go_to_previous_ayah)

        self.headerbar.popover_telaawa.connect(
            'go-to-next-ayah', self.headerbar.popover_nav_alt.go_to_next_ayah)
        self.headerbar.popover_telaawa.connect(
            'go-to-previous-ayah',
            self.headerbar.popover_nav_alt.go_to_previous_ayah)

        self.headerbar.popover_listofcontents.connect(
            'go-to-suraya', self.headerbar.popover_nav.go_to_suraya)
        self.headerbar.popover_listofcontents.connect(
            'go-to-suraya', self.headerbar.popover_nav_alt.go_to_suraya)

        self.button_next_page.connect(
            'clicked', self.headerbar.popover_nav.go_to_next_page)
        self.button_previous_page.connect(
            'clicked', self.headerbar.popover_nav.go_to_previous_page)

        self.button_next_page.connect(
            'clicked', self.headerbar.popover_nav_alt.go_to_next_page)
        self.button_previous_page.connect(
            'clicked', self.headerbar.popover_nav_alt.go_to_previous_page)

        self.headerbar.popover_menu.connect('page-scaled', self.resize_musshaf)
        self.headerbar.popover_menu.connect('dualpage-toggled',
                                            self.toggle_dualpage)
        self.headerbar.popover_menu.connect('nightmode-toggled',
                                            self.toggle_nightmode)

    def setup_musshaf_viewer(self) -> None:
        self.musshaf_viewer_right = MusshafViewer(0)
        self.main_paned.pack_end(self.musshaf_viewer_right, True, True, 0)
        self.musshaf_viewer_right.image.set_halign(Gtk.Align.START)
        self.musshaf_viewer_right.eventbox.set_halign(Gtk.Align.START)

        self.musshaf_viewer_left = MusshafViewer(1)
        self.musshaf_viewer_left.image.set_halign(Gtk.Align.END)
        self.musshaf_viewer_left.eventbox.set_halign(Gtk.Align.END)
        self.main_paned.pack_start(self.musshaf_viewer_left, True, True, 0)

        if glob.night_mode:
            self.main_paned.set_name('musshaf-dark')
        else:
            self.main_paned.set_name('musshaf-light')

        self.headerbar.popover_nav.connect('reload-musshaf-viewer',
                                           self.reload_musshaf_viewer)
        self.headerbar.popover_nav.connect('reload-musshaf-viewer',
                                           self.toggle_bookmark)
        self.headerbar.popover_nav.connect('reload-tarajem-viewer',
                                           self.reload_tarajem_viewer)
        self.headerbar.popover_nav.connect('reload-telaawa-player',
                                           self.reload_telaawa_player)

        self.headerbar.popover_nav_alt.connect('reload-musshaf-viewer',
                                               self.reload_musshaf_viewer)
        self.headerbar.popover_nav_alt.connect('reload-musshaf-viewer',
                                               self.toggle_bookmark)
        self.headerbar.popover_nav_alt.connect('reload-tarajem-viewer',
                                               self.reload_tarajem_viewer)
        self.headerbar.popover_nav_alt.connect('reload-telaawa-player',
                                               self.reload_telaawa_player)

        self.musshaf_viewer_right.connect('selected-ayah-changed',
                                          self.reload_navigation_panel)
        self.musshaf_viewer_right.connect('hovered-ayah-changed',
                                          self.reload_tarajem_viewer)
        self.musshaf_viewer_right.connect('focused-page-changed',
                                          self.reload_tarajem_viewer)

        self.musshaf_viewer_left.connect('selected-ayah-changed',
                                         self.reload_navigation_panel)
        self.musshaf_viewer_left.connect('hovered-ayah-changed',
                                         self.reload_tarajem_viewer)
        self.musshaf_viewer_left.connect('focused-page-changed',
                                         self.reload_tarajem_viewer)

    def setup_tarajem_viewer(self) -> None:
        self.tarajem_viewer = TarajemViewer()

    def setup_window_size(self) -> None:
        """Scale the window to fit all its visible contents

        The size is calculated from scaled two-side image pages (or a page).
        For its height, the headerbar height is added.
        """
        musshaf_dir = path.join(const.USER_DATA_PATH,
                                f'musshaf/{glob.musshaf_name}')

        # Load a sample image page of the opened Musshaf ID by assuming that
        # all image pages have the same size
        image_filepath = path.join(musshaf_dir, '1.jpg')
        page_image = GdkPixbuf.Pixbuf.new_from_file(image_filepath)

        page_width = round(page_image.get_width() * glob.page_scale)
        page_height = round(page_image.get_height() * glob.page_scale)

        headerbar_size = self.headerbar.get_allocation()
        window_height = page_height + headerbar_size.height

        if glob.dual_page:
            window_width = page_width * 2 + const.PAGE_MARGIN / 2 * 3
        else:
            window_width = page_width

        self.resize(window_width, window_height + const.PAGE_MARGIN)
        self.tarajem_viewer.scrolledwindow.set_size_request(
            page_width, page_height)

        if glob.dual_page:
            window_width = window_width + 52
        else:
            window_width = window_width + 72

        self.set_size_request(window_width, self.get_size_request()[1])

    @Gtk.Template.Callback()
    def on_key_press(self, window: Gtk.Window, event: Gdk.EventKey) -> None:
        if event.keyval == Gdk.KEY_Left:
            self.headerbar.popover_nav.go_to_next_page()
            self.headerbar.popover_nav_alt.go_to_next_page()

        elif event.keyval == Gdk.KEY_Right:
            self.headerbar.popover_nav.go_to_previous_page()
            self.headerbar.popover_nav_alt.go_to_previous_page()

        elif event.keyval == Gdk.KEY_Up:
            self.headerbar.popover_nav.go_to_previous_ayah(
                fixed_surah_no=False)
            self.headerbar.popover_nav_alt.go_to_previous_ayah(
                fixed_surah_no=False)

        elif event.keyval == Gdk.KEY_Down:
            self.headerbar.popover_nav.go_to_next_ayah(fixed_surah_no=False)
            self.headerbar.popover_nav_alt.go_to_next_ayah(
                fixed_surah_no=False)

    @Gtk.Template.Callback()
    def on_key_release(self, window: Gtk.Window, event: Gdk.EventKey) -> None:
        ...

    @Gtk.Template.Callback()
    def on_loses_focus(self, window: Gtk.Window,
                       event: Gdk.EventFocus) -> None:
        ...

    @Gtk.Template.Callback()
    def on_quit(self, widget: Gtk.Widget) -> None:
        # Free resources
        player = self.headerbar.popover_telaawa
        player.playbin.set_state(Gst.State.NULL)
        Gst.Object.unref(player.playbin)
        if player.playbin_seeker:
            GLib.source_remove(player.playbin_seeker)

    @Gtk.Template.Callback()
    def on_buttonnav_entered(self, widget: Gtk.Widget,
                             event: Gdk.EventCrossing) -> None:
        widget.get_children()[0].set_reveal_child(True)

    @Gtk.Template.Callback()
    def on_buttonnav_left(self, widget: Gtk.Widget,
                          event: Gdk.EventCrossing) -> None:
        widget.get_children()[0].set_reveal_child(False)

    def reload_navigation_panel(self, widget: Gtk.Widget) -> None:
        if not glob.mobile_view:
            self.headerbar.popover_nav.update()
        else:
            self.headerbar.popover_nav_alt.update()

    def reload_musshaf_viewer(self, widget: Gtk.Widget) -> None:
        self.musshaf_viewer_right.update()
        if glob.dual_page:
            self.musshaf_viewer_left.update()

    def reload_tarajem_viewer(self, widget: Gtk.Widget) -> None:
        if self.page_focused != glob.page_focused \
                or self.tarajem_visibility != glob.tarajem_visibility:
            self.tarajem_visibility = glob.tarajem_visibility

            self.main_paned.remove(self.musshaf_viewer_right)
            self.main_paned.remove(self.tarajem_viewer)
            self.main_paned.remove(self.musshaf_viewer_left)

            if glob.dual_page:
                self.musshaf_viewer_right.image.set_halign(Gtk.Align.START)
                self.musshaf_viewer_right.eventbox.set_halign(Gtk.Align.START)

                if glob.tarajem_visibility \
                        and glob.page_focused >= 0:  # a negative is invalid
                    # If the right Musshaf viewer is on focus, replace the left
                    # Musshaf viewer with tarajem viewer and vice versa.
                    if glob.page_focused == self.musshaf_viewer_right.id:
                        self.main_paned.remove(self.musshaf_viewer_left)
                        self.tarajem_viewer.set_halign(Gtk.Align.END)
                        self.main_paned.pack_start(self.tarajem_viewer, True,
                                                   True, 0)
                        self.main_paned.pack_end(self.musshaf_viewer_right,
                                                 True, True, 0)
                    else:
                        self.main_paned.remove(self.musshaf_viewer_right)
                        self.tarajem_viewer.set_halign(Gtk.Align.START)
                        self.main_paned.pack_end(self.tarajem_viewer, True,
                                                 True, 0)
                        self.main_paned.pack_start(self.musshaf_viewer_left,
                                                   True, True, 0)
                else:
                    # If tarajem opening is not requested, display only Musshaf
                    # viewer(s)
                    self.main_paned.pack_start(self.musshaf_viewer_left, True,
                                               True, 0)
                    self.main_paned.pack_end(self.musshaf_viewer_right, True,
                                             True, 0)
            else:
                self.main_paned.pack_end(self.musshaf_viewer_right, True, True,
                                         0)
                self.musshaf_viewer_right.image.set_halign(Gtk.Align.CENTER)
                self.musshaf_viewer_right.eventbox.set_halign(Gtk.Align.CENTER)

        # TODO: support displaying tarajem on mobile view mode
        if not glob.tarajem_visibility \
                or not glob.dual_page:
            return

        is_page_no_updated = self.page_number != glob.page_number
        if is_page_no_updated:
            self.page_number = glob.page_number

        is_tarajem_names_updated = self.tarajem_names != glob.tarajem_names
        if is_tarajem_names_updated:
            self.tarajem_names = deepcopy(glob.tarajem_names)

        is_content_updated = is_page_no_updated \
            or is_tarajem_names_updated

        # Populate tarajem based on the page where the focused ayah is
        # located
        if glob.page_focused == self.musshaf_viewer_right.id:
            self.tarajem_viewer.populate(
                self.musshaf_viewer_right.bboxes,
                self.musshaf_viewer_right.bboxes_hovered,
                self.musshaf_viewer_right.bboxes_focused, is_content_updated)
        else:
            self.tarajem_viewer.populate(
                self.musshaf_viewer_left.bboxes,
                self.musshaf_viewer_left.bboxes_hovered,
                self.musshaf_viewer_left.bboxes_focused, is_content_updated)

    def reload_telaawa_player(self, widget: Gtk.Widget) -> None:
        state = self.surah_number != glob.surah_number \
            or self.ayah_number != glob.ayah_number
        self.surah_number = glob.surah_number
        self.ayah_number = glob.ayah_number

        player = self.headerbar.popover_telaawa
        if not player.ready_to_play:
            player.playback(TelaawaPlayerState.STOP)
            return

        if state:
            player.playback(TelaawaPlayerState.PLAY)
        else:
            player.playback(TelaawaPlayerState.STOP)

    def toggle_bookmark(self, widget: Gtk.Widget) -> None:
        for bookmark in glob.bookmark_names:
            musshaf_name, page_number, _ = bookmark.split(';')
            page_number = int(page_number)

            if musshaf_name != glob.musshaf_name:
                continue

            if page_number == glob.page_number:
                is_bookmarked = True
                break
        else:
            is_bookmarked = False

        self.headerbar.is_updating = True
        self.headerbar.button_toggle_bookmark.set_active(is_bookmarked)
        self.headerbar.is_updating = False

    def resize_musshaf(self, widget: Gtk.Widget) -> None:
        # FIXME: widget allocations are not updated immediately
        self.musshaf_viewer_right.update(True)
        if glob.dual_page:
            self.musshaf_viewer_left.update(True)
        self.setup_window_size()

    def toggle_dualpage(self, widget: Gtk.Widget) -> None:
        self.reload_tarajem_viewer(widget)
        self.resize_musshaf(widget)
        self.setup_window_size()

    def toggle_nightmode(self, widget: Gtk.Widget) -> None:
        self.musshaf_viewer_right.update(True)
        if glob.dual_page:
            self.musshaf_viewer_left.update(True)

        if glob.night_mode:
            self.main_paned.set_name('musshaf-dark')
        else:
            self.main_paned.set_name('musshaf-light')
Ejemplo n.º 27
0
    def do_startup(self):
        Gtk.Application.do_startup(self)

        Handy.init()
Ejemplo n.º 28
0
class SpotipyneWindow(Handy.ApplicationWindow):
    __gtype_name__ = 'SpotipyneWindow'

    Handy.init()
    headerbar_switcher = Gtk.Template.Child()
    bottom_switcher = Gtk.Template.Child()
    player_deck = Gtk.Template.Child()
    main_stack = Gtk.Template.Child()
    back_button_stack = Gtk.Template.Child()
    back_button_playlists = Gtk.Template.Child()
    back_button_search = Gtk.Template.Child()
    simple_controls_parent = Gtk.Template.Child()

    def init_cover_art_loader(self):
        self.cover_art_loader = CoverArtLoader()

    def init_spotify_playback(self):
        self.spotify_playback = SpotifyPlayback(self.cover_art_loader)

    def init_simple_controls(self):
        self.simple_controls = SimpleControls(self.spotify_playback)
        self.simple_controls_parent.pack_start(self.simple_controls, False,
                                               True, 0)
        self.simple_controls.set_reveal_child(False)

    def init_library_overview(self):
        self.library_overview = LibraryOverview(self.sp_gui,
                                                self.back_button_playlists)
        self.main_stack.add_titled(self.library_overview, 'Library', 'Library')
        self.main_stack.child_set_property(self.library_overview, 'icon-name',
                                           'applications-multimedia-symbolic')

    def init_search_overview(self):
        self.search_overview = SearchOverview(self.sp_gui,
                                              self.back_button_search)
        self.main_stack.add_titled(self.search_overview, 'Search', 'Search')
        self.main_stack.child_set_property(self.search_overview, 'icon-name',
                                           'edit-find-symbolic')

    def init_back_buttons(self):
        self.back_button_stack.child_set_property
        self.main_stack.bind_property("visible-child-name",
                                      self.back_button_stack,
                                      "visible-child-name")

    def init_login(self):
        self.login_page = Login(self.on_logged_in)
        self.player_deck.add(self.login_page)
        self.player_deck.set_visible_child(self.login_page)
        self.player_deck.show_all()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.init_login()

    def on_logged_in(self):
        self.player_deck.remove(self.login_page)
        self.player_deck.set_visible_child(self.player_deck.get_children()[0])

        self.init_cover_art_loader()

        self.sp_gui = SpotifyGuiBuilder(self.cover_art_loader)

        self.init_library_overview()

        self.init_search_overview()

        self.init_spotify_playback()

        self.init_simple_controls()

        self.init_back_buttons()

        self.headerbar_switcher.bind_property("title-visible",
                                              self.bottom_switcher, "reveal",
                                              GObject.BindingFlags.SYNC_CREATE)
Ejemplo n.º 29
0
class CpupowerGuiWindow(Gtk.ApplicationWindow):
    __gtype_name__ = "CpupowerGuiWindow"

    Handy.init()
    cpu_box = Gtk.Template.Child()
    gov_box = Gtk.Template.Child()
    adj_min = Gtk.Template.Child()
    adj_max = Gtk.Template.Child()
    spin_min = Gtk.Template.Child()
    spin_max = Gtk.Template.Child()
    min_sl = Gtk.Template.Child()
    max_sl = Gtk.Template.Child()
    apply_btn = Gtk.Template.Child()
    toall = Gtk.Template.Child()
    about_dialog = Gtk.Template.Child()
    profile_box = Gtk.Template.Child()
    default_profile_pref = Gtk.Template.Child()
    energy_pref_box = Gtk.Template.Child()
    tree_view = Gtk.Template.Child()
    headerbar_switcher = Gtk.Template.Child()
    bottom_switcher = Gtk.Template.Child()
    squeezer = Gtk.Template.Child()
    default_allcpus = Gtk.Template.Child()
    default_ticks = Gtk.Template.Child()
    default_ticks_num = Gtk.Template.Child()
    default_energy_per_cpu = Gtk.Template.Child()
    energy_pref_percpu = Gtk.Template.Child()
    profile_overview = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.squeezer.connect("notify::visible-child",
                              self.on_headerbar_squeezer_notify)
        # Read configuration
        self.conf = CpuPowerConfig()
        # Get GUI config and profiles
        self.gui_conf = self.conf.get_gui_settings()
        self.profiles = self.conf.profiles
        self.profile = None

        self.refreshing = False
        self.settings = {}
        self.energy_pref_avail = False
        self.energy_per_cpu = False
        self.tree_store = None
        self.tick_marks_enabled = True
        self.ticks_markup = True
        self.selected_cpus = None

        self.style_ctx = self.tree_view.get_style_context()
        self.fg = self.style_ctx.get_color(Gtk.StateFlags.NORMAL).to_string()
        self.update_cpubox()
        self.load_cpu_settings()
        self._update_tree_view()
        self.configure_gui()
        self.upd_sliders()

        GLib.timeout_add(500, self._update_current_freq)
        # Application actions
        action = Gio.SimpleAction.new("Exit", None)
        action.connect("activate", self.quit)
        self.add_action(action)

    def on_headerbar_squeezer_notify(self, squeezer, event):
        child = squeezer.get_visible_child()
        self.bottom_switcher.set_reveal(child != self.headerbar_switcher)
        self.gov_box.set_use_subtitle(child != self.headerbar_switcher)
        self.energy_pref_box.set_use_subtitle(child != self.headerbar_switcher)
        self.cpu_box.set_use_subtitle(child != self.headerbar_switcher)

    @contextmanager
    def lock(self):
        """Helper function to stop widgets from refreshing"""
        self.refreshing = True
        yield
        self.refreshing = False

    def load_cpu_settings(self):
        """Initialise the configuration store"""
        for cpu in self.online_cpus:
            self.settings[cpu] = CpuSettings(cpu)
            self._update_treeview_style(cpu, False)
        self.energy_pref_avail = self.settings[0].energy_pref_avail

    def update_cpubox(self):
        """Update the CPU Combobox"""
        self.cpu_store = Gio.ListStore()
        self.cpu_box.bind_name_model(self.cpu_store, lambda x: x.name)

        for cpu in self.online_cpus:
            self.cpu_store.append(CpuCore(cpu))

        self.cpu_box.set_selected_index(0)

    def configure_gui(self):
        """Configures GUI based on the config file"""

        # Add prefix checkbutton to cpu
        self.cpu_online = Gtk.CheckButton()
        self.cpu_online.connect("toggled", self.on_cpu_online_toggled)
        self.cpu_box.add_prefix(self.cpu_online)
        self.cpu_online.show()

        # Preferences
        toggle_default = self.gui_conf.getboolean("allcpus_default", False)
        self.toall.set_active(toggle_default)
        self.default_allcpus.set_active(toggle_default)

        default_ticks = self.gui_conf.getboolean("tick_marks_enabled", True)
        self.tick_marks_enabled = default_ticks
        self.default_ticks.set_active(default_ticks)

        default_ticks_num = self.gui_conf.getboolean("frequency_ticks", True)
        self.ticks_markup = default_ticks_num
        self.default_ticks_num.set_active(default_ticks_num)

        default_energy_percpu = self.gui_conf.getboolean(
            "energy_pref_per_cpu", False)
        self.energy_per_cpu = default_energy_percpu
        self.default_energy_per_cpu.set_active(default_energy_percpu)

        self.update_profile_boxes()

        self.generate_profiles_page()

        # Check if intel pstate perfs are available
        if self.energy_pref_avail:
            self.energy_pref_box.set_visible(True)
            self.energy_pref_percpu.set_visible(True)

    def update_profile_boxes(self):
        # Configure profiles box
        self.prof_store = Gio.ListStore()

        # Empty profile name to use for resetting settings
        self.prof_store.append(Profile(_("No profile")))

        # Add the profiles from configuration
        for prof in self.conf.profiles:
            profile = self.conf.get_profile(prof)
            self.prof_store.append(Profile(profile))

        self.profile_box.bind_name_model(self.prof_store, lambda x: x.name)

        # Add the profiles from configuration to prefs
        model = Gio.ListStore()
        for prof in self.conf.profiles:
            model.append(Profile(prof))

        index = self.conf.get_profile_index(self.conf.default_profile)
        self.default_profile_pref.bind_name_model(model, lambda x: x.name)
        self.default_profile_pref.set_selected_index(index)

    def generate_profiles_page(self):
        """Create preference groups for profiles"""
        new_profile = Handy.PreferencesGroup(title=_("New profile"))
        self.custom_profiles = Handy.PreferencesGroup(title=_("User profiles"))
        self.system_profiles = Handy.PreferencesGroup(
            title=_("System profiles"))
        self.builtin_profiles = Handy.PreferencesGroup(
            title=_("Built-in profiles"))
        self.profile_overview.add(new_profile)
        self.profile_overview.add(self.custom_profiles)
        self.profile_overview.add(self.system_profiles)
        self.profile_overview.add(self.builtin_profiles)

        # Add entry for current profile
        prof_entry = Handy.ActionRow(title=_("Profile name"))
        save_me = Gtk.Button.new_from_icon_name("document-save", 1)
        save_me.set_sensitive(False)
        self.profile_name_entry = Gtk.Entry(placeholder_text=_("Name"))
        self.profile_name_entry.connect("changed", self.on_prof_name_changed,
                                        save_me)
        prof_entry.add(self.profile_name_entry)
        prof_entry.add(save_me)
        save_me.connect("clicked", self.on_save_profile_clicked)
        prof_entry.set_activatable_widget(save_me)
        new_profile.add(prof_entry)

        self._generate_profile_list()

    def update_profiles_page(self):
        """Update listed profiles"""
        for child in self.custom_profiles.get_children():
            child.destroy()
        for child in self.system_profiles.get_children():
            child.destroy()
        for child in self.builtin_profiles.get_children():
            child.destroy()
        self._generate_profile_list()

    def _generate_profile_list(self):
        """Create profile listings using fresh config"""
        # Add entries for saved profiles
        for prof in self.conf.profiles:
            profile = self.conf.get_profile(prof)
            prof_entry = Handy.ActionRow()
            prof_entry.set_title(prof)
            if profile._custom:
                if not profile.system:
                    delete_me = Gtk.Button.new_from_icon_name("edit-delete", 1)
                    prof_entry.add(delete_me)
                    delete_me.connect("clicked",
                                      self.on_delete_profile_clicked, prof)
                    prof_entry.set_activatable_widget(delete_me)
                    self.custom_profiles.add(prof_entry)
                else:
                    self.system_profiles.add(prof_entry)
            else:
                self.builtin_profiles.add(prof_entry)

        self.profile_overview.show_all()

    def quit(self, *args):
        """Quit"""
        HELPER.quit()
        exit(0)

    def _reset_energy_conf(self, cpu):
        if cpu == -1:
            # Reset conf for all cpus
            for cpu, conf in self.settings.items():
                conf.reset_energy_pref()
                self._update_treeview_style(cpu, conf.changed)
            return

        self.settings[cpu].reset_energy_pref()

    def _update_settings_freqs(self, cpu, fmin, fmax):
        """Updates settings frequency values for `cpu`

        Args:
            cpu: Index of cpu to update
            fmin: Minimum scaling frequency
            fmax: Minimum scaling frequency

        """
        if self.toall.get_active():
            for cpu, row in enumerate(self.tree_store):
                conf = self.settings.get(cpu)
                if conf is not None:
                    conf.freqs = (fmin, fmax)
                row[2] = fmin
                row[3] = fmax
                self._update_treeview_style(cpu, conf.changed)
        else:
            conf = self.settings.get(cpu)
            if conf is not None:
                conf.freqs = (fmin, fmax)
            self.tree_store[cpu][2] = fmin
            self.tree_store[cpu][3] = fmax
            self._update_treeview_style(cpu, conf.changed)

    def _update_settings_online(self, cpu, online):
        """Updates settings online value for `cpu`

        Args:
            cpu: Index of cpu to update
            online: Boolean indication if cpu is online or offline

        """
        conf = self.settings.get(cpu)

        if conf is not None:
            conf.online = online
        self._update_treeview_style(cpu, conf.changed)

    def _update_treeview_style(self, cpu, changed):
        """Change style on the tree view if cpu settings were changed

        Args:
            cpu: Index of cpu to update
            changed: If changed is True, cpu text will be coloured red,
             otherwise the text will be black

        """
        style = 1 if changed else 0
        if cpu <= len(self.settings):
            if self.tree_store:
                self.tree_store[cpu][6] = style

    def upd_sliders(self):
        """Updates the slider widgets by reading the sys files"""
        cpu = self._get_active_cpu()
        conf = self.settings.get(cpu)
        if not conf:
            return

        freq_min_hw, freq_max_hw = conf.hw_lims
        cpu_online = conf.online
        freq_min, freq_max = conf.freqs

        with self.lock():  # Use the flag to skip callbacks
            self._update_gov_box()
            if self.energy_pref_avail:
                self._update_energy_pref_box()

            # Update sliders
            self._set_sliders_sensitive(cpu_online)
            self._update_frequency_marks(cpu)
            self.adj_min.set_lower(freq_min_hw)
            self.adj_min.set_upper(freq_max_hw)
            self.adj_max.set_lower(freq_min_hw)
            self.adj_max.set_upper(freq_max_hw)
            self.adj_min.set_value(freq_min)
            self.adj_max.set_value(freq_max)

            self.apply_btn.set_sensitive(self.is_conf_changed)
            self.cpu_online.set_active(cpu_online)
            self.cpu_online.set_sensitive(bool(
                HELPER.cpu_allowed_offline(cpu)))

        self._update_treeview_style(cpu, conf.changed)

    def _get_active_cpu(self):
        """Helper function to get cpu from combobox"""
        # cpu_iter = self.cpu_box.get_active_iter()
        index = self.cpu_box.get_selected_index()
        if index != -1:
            return index
        # if cpu_iter is not None:
        #    return int(self.cpu_store[cpu_iter][0])

        # self.update_cpubox()
        return 0

    def _set_profile_settings(self, profile):
        """Set the settings based on the selected profile"""
        self.load_cpu_settings()  # Discard any changes

        # If no profile selected reset and disable apply_btn
        if profile.name == _("No profile"):
            self.toall.set_sensitive(True)
            for cpu, conf in self.settings.items():
                conf.reset_conf()
                self.update_tree_view(cpu, conf)
            return False

        self.toall.set_active(False)  # Turn off toggle
        self.toall.set_sensitive(False)  # Disable toggle
        prof_settings = profile.settings
        for cpu, settings in prof_settings.items():
            conf = self.settings.get(cpu)
            if not conf:
                continue
            conf.freqs_scaled = settings["freqs"]
            if settings["governor"] in conf.governors:
                conf.governor = settings["governor"]
            conf.online = settings["online"]
            self.update_tree_view(cpu, conf)
            self._update_treeview_style(cpu, conf.changed)
        return True

    def _set_sliders_sensitive(self, state):
        """Enable/Disable sliders and combo boxes"""
        self.spin_min.set_sensitive(state)
        self.spin_max.set_sensitive(state)
        self.min_sl.set_sensitive(state)
        self.max_sl.set_sensitive(state)
        self.gov_box.set_sensitive(state)
        self.energy_pref_box.set_sensitive(state)

    def _update_frequency_marks(self, cpu):
        """Add or remove slider marks for frequency steps

        Args:
            cpu: Index of cpu to query

        """
        # Clear marks
        self.min_sl.clear_marks()
        self.max_sl.clear_marks()

        if not self.tick_marks_enabled:
            return

        steps = self.get_cpu_frequency_steps(cpu)
        if not steps:
            minf = self.adj_min.get_lower()
            maxf = self.adj_min.get_upper()
            steps = [minf, maxf - (maxf - minf) / 2, maxf]

        markup = "{:1.2f}"
        for frequency in steps:
            freq = float(frequency / 1e3)
            mark = markup.format(freq)
            if self.ticks_markup:
                self.min_sl.add_mark(frequency, Gtk.PositionType.TOP, mark)
            else:
                self.min_sl.add_mark(frequency, Gtk.PositionType.TOP)
            self.max_sl.add_mark(frequency, Gtk.PositionType.TOP)

    def _update_energy_pref_box(self):
        """Updates the energy performance combobox"""
        cpu = self._get_active_cpu()
        conf = self.settings.get(cpu)

        energy_pref = conf.energy_pref_id
        energy_prefs = conf.energy_prefs

        if energy_pref != -1:
            pref_store = Gio.ListStore()
            for prefid, pref in enumerate(energy_prefs):
                if "_" in pref:
                    pref = pref.replace("_", " ")
                pref_store.append(EnergyPref(prefid, pref.capitalize()))

            self.energy_pref_box.bind_name_model(pref_store, lambda x: x.name)
            self.energy_pref_box.set_selected_index(energy_pref)
            self.energy_pref_box.set_sensitive(True)
        else:
            self.energy_pref_box.set_sensitive(False)

    def _update_gov_box(self):
        """Updates the governor combobox"""
        cpu = self._get_active_cpu()
        conf = self.settings.get(cpu)

        governor = conf.govid
        governors = conf.governors

        if governor is not None:
            gov_store = Gio.ListStore()
            for govid, gov in enumerate(governors):
                gov_store.append(Governor(govid, gov.capitalize()))

            self.gov_box.bind_name_model(gov_store, lambda x: x.name)
            self.gov_box.set_selected_index(governor)
            self.gov_box.set_sensitive(True)
        else:
            self.gov_box.set_sensitive(False)

    def _update_current_freq(self):
        """Callback to update the tree view with current CPU frequency"""
        for cpu in self.online_cpus:
            current_freq = read_current_freq(cpu) / 1e3
            self.tree_store[cpu][5] = current_freq
        return True

    def on_freq_edited(self, widget, path, value, index):
        """Update the sliders when frequencies change from table"""
        value = float(value)
        cpu = int(path)
        conf = self.settings[cpu]
        fmin, fmax = conf.freqs

        if cpu == self._get_active_cpu():
            if index == 2:
                self.adj_min.set_value(value)
            else:
                self.adj_max.set_value(value)
        else:
            if index == 2:
                conf.freqs = value, fmax
            else:
                conf.freqs = fmin, value

    def on_tree_toggled(self, widget, path):
        """Update online cpu toggle"""
        # check if it can be disabled
        allowed = bool(HELPER.cpu_allowed_offline(int(path)))
        if not allowed:
            return

        online = not self.tree_store[path][1]
        self.tree_store[path][1] = online
        self.settings[int(path)].online = online
        if int(path) == self._get_active_cpu():
            self.cpu_online.set_active(online)

    def _update_tree_view(self):
        """Updates the tree view"""
        self.tree_store = Gtk.ListStore(int, bool, float, float, str, float,
                                        int)
        for cpu, conf in self.settings.items():
            fmin, fmax = conf.freqs
            self.tree_store.append([
                cpu, conf.online, fmin, fmax,
                conf.governor.capitalize(), 0.0, 0
            ])

        for i, column_title in enumerate([
                _("CPU"),
                _("Online"),
                _("Min"),
                _("Max"),
                _("Governor"),
                _("Current freq."),
        ]):
            if column_title == _("Online"):
                renderer = Gtk.CellRendererToggle()
                renderer.connect("toggled", self.on_tree_toggled)
                column = Gtk.TreeViewColumn(column_title, renderer, active=i)

            elif column_title == _("Current freq."):
                renderer = Gtk.CellRendererSpin(digits=2)
                column = Gtk.TreeViewColumn(column_title,
                                            renderer,
                                            text=i,
                                            style=6)
                column.set_cell_data_func(renderer, self.conv_float, 5)

            elif column_title in [_("Min"), _("Max")]:
                index = 2 if column_title == _("Min") else 3
                adj = Gtk.Adjustment(
                    value=0,
                    lower=fmin,
                    upper=fmax,
                    step_increment=10,
                    page_increment=50,
                    page_size=0,
                )
                renderer = Gtk.CellRendererSpin(editable=True,
                                                adjustment=adj,
                                                digits=2)
                renderer.connect("edited", self.on_freq_edited, index)
                column = Gtk.TreeViewColumn(column_title,
                                            renderer,
                                            text=i,
                                            style=6)
                column.set_cell_data_func(renderer, self.conv_float, index)
            else:
                renderer = Gtk.CellRendererText()
                column = Gtk.TreeViewColumn(column_title,
                                            renderer,
                                            text=i,
                                            style=6)
            self.tree_view.append_column(column)

        self.tree_view.set_model(self.tree_store)

    def update_tree_view(self, cpu, conf):
        """Update values inside the tree view"""
        if cpu == -1:
            for row in self.tree_store:
                row[2], row[3] = conf.freqs
                row[1] = conf.online
                row[4] = conf.governor.capitalize()
        else:
            row = self.tree_store[cpu]
            row[2], row[3] = conf.freqs
            row[1] = conf.online
            row[4] = conf.governor.capitalize()

    @Gtk.Template.Callback()
    def on_tree_selection(self, selection):
        model, treeiter = selection.get_selected()
        if treeiter is not None:
            self.cpu_box.set_selected_index(model[treeiter][0])

    @Gtk.Template.Callback()
    def on_prefs_changed(self, pref, value):
        name = Gtk.Buildable.get_name(pref)
        value_str = str(value)
        if name == "default_profile_pref":
            mod = pref.get_model()
            ind = self.default_profile_pref.get_selected_index()
            self.conf.set("Profile", "profile", mod[ind].name)
        elif name == "default_allcpus":
            self.gui_conf["allcpus_default"] = value_str
        elif name == "default_ticks":
            self.tick_marks_enabled = value
            self.gui_conf["tick_marks_enabled"] = value_str
            self._update_frequency_marks(self._get_active_cpu())
        elif name == "default_ticks_num":
            self.ticks_markup = value
            self.gui_conf["frequency_ticks"] = value_str
            self._update_frequency_marks(self._get_active_cpu())
        elif name == "default_energy_per_cpu":
            self.gui_conf["energy_pref_per_cpu"] = value_str
            self.energy_per_cpu = value

        self.conf.write_settings()

    @Gtk.Template.Callback()
    def on_cpu_changed(self, widget, value):
        """Callback for cpu box"""
        # pylint: disable=W0612,W0613
        selection = self.tree_view.get_selection()
        index = widget.get_selected_index()
        if index > -1:
            selection.select_path(index)
        self.upd_sliders()

    @Gtk.Template.Callback()
    def on_toall_toggled(self, widget):
        """Enable/Disable cpu_box"""
        cpu = self._get_active_cpu()
        settings = self.settings[cpu]
        if widget.get_active():
            for cpu, conf in self.settings.items():
                conf.freqs = settings.freqs
                conf.governor = settings.governor
                conf.online = settings.online
                conf.energy_pref = settings.energy_pref
                self.update_tree_view(cpu, conf)
        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_adj_min_value_changed(self, *args):
        """Callback for adj_min"""
        # pylint: disable=W0612,W0613
        if self.refreshing:
            return
        cpu = self._get_active_cpu()
        fmin = self.adj_min.get_value()
        fmax = self.adj_max.get_value()
        fmin_hw, fmax_hw = self.settings[cpu].hw_lims

        if fmin > fmax:
            if fmin + 10 > fmax_hw:
                fmax = fmax_hw
            else:
                fmax = fmin + 10
        elif fmax < fmin:
            if fmax - 10 < fmin_hw:
                fmin = fmin_hw
            else:
                fmin = fmax - 10

        with self.lock():
            self.adj_min.set_value(fmin)
            self.adj_max.set_value(fmax)

        self._update_settings_freqs(cpu, fmin, fmax)
        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_adj_max_value_changed(self, *args):
        """Callback for adj_max"""
        # pylint: disable=W0612,W0613
        if self.refreshing:
            return
        cpu = self._get_active_cpu()
        fmin = self.adj_min.get_value()
        fmax = self.adj_max.get_value()

        if fmax < fmin:
            fmin = fmax - 10

        with self.lock():
            self.adj_min.set_value(fmin)

        self._update_settings_freqs(cpu, fmin, fmax)
        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_refresh_clicked(self, *args):
        """Callback for refresh button"""
        if self.toall.get_active():
            for cpu in self.settings.keys():
                self._refresh_cpu_settings(cpu)
        else:
            cpu = self._get_active_cpu()
            self._refresh_cpu_settings(cpu)

    def _refresh_cpu_settings(self, cpu):
        self.settings[cpu].update_conf()
        self.update_tree_view(cpu, self.settings[cpu])

        if self.energy_pref_avail:
            if not self.energy_per_cpu:
                self._reset_energy_conf(-1)
            else:
                self._reset_energy_conf(cpu)
        self.upd_sliders()

    def on_cpu_online_toggled(self, *args):
        """Callback for cpu_online toggle"""
        if self.refreshing:
            return
        cpu = self._get_active_cpu()
        conf = self.settings[cpu]
        conf.online = self.cpu_online.get_active()
        self._set_sliders_sensitive(conf.online)
        self.apply_btn.set_sensitive(self.is_conf_changed)
        self.tree_store[cpu][1] = conf.online
        self._update_treeview_style(cpu, conf.changed)

    @Gtk.Template.Callback()
    def on_governor_changed(self, *args):
        """Callback for governor combobox
        Change governor and enable apply_btn
        """
        # pylint: disable=W0612,W0613
        if self.refreshing:
            return
        mod = self.gov_box.get_model()
        gov = mod[self.gov_box.get_selected_index()]
        # Update store
        if self.toall.get_active():
            for cpu, row in enumerate(self.tree_store):
                conf = self.settings.get(cpu)
                conf.governor = gov.govid
                row[4] = gov.name
                self._update_treeview_style(cpu, conf.changed)
        else:
            cpu = self._get_active_cpu()
            conf = self.settings.get(cpu)
            conf.governor = gov.govid
            self.tree_store[cpu][4] = gov.name
            self._update_treeview_style(cpu, conf.changed)

        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_energy_pref_box_changed(self, *args):
        """Callback for energy combobox
        Change energy pref and enable apply_btn
        """
        # pylint: disable=W0612,W0613
        if self.refreshing:
            return
        mod = self.energy_pref_box.get_model()
        energy_pref = mod[self.energy_pref_box.get_selected_index()]
        active_cpu = self._get_active_cpu()

        # Note that tasks may by migrated from one CPU to another by the scheduler’s
        # load-balancing algorithm and if different energy vs performance hints are
        # set for those CPUs, that may lead to undesirable outcomes.
        # To avoid such issues it is better to set the same energy vs performance hint
        # for all CPUs or to pin every task potentially sensitive to them
        # to a specific CPU.
        # https://www.kernel.org/doc/html/v4.12/admin-guide/pm/intel_pstate.html#energy-vs-performance-hints

        error = False
        if self.energy_per_cpu:
            conf = self.settings.get(active_cpu)
            if conf.governor == "performance" and energy_pref.name != "Performance":
                error = True
                with self.lock():
                    self.energy_pref_box.set_selected_index(
                        conf.energy_pref_id)
            else:
                conf.energy_pref = energy_pref.prefid
                self._update_treeview_style(active_cpu, conf.changed)

        else:
            for cpu, conf in self.settings.items():
                if conf.governor == "performance" and energy_pref.name != "Performance":
                    error = True
                    if cpu == active_cpu:
                        with self.lock():
                            self.energy_pref_box.set_selected_index(
                                conf.energy_pref_id)
                    continue
                conf.energy_pref = energy_pref.prefid
                self._update_treeview_style(cpu, conf.changed)

        if error:
            error_message(
                _("Energy profiles other than performance are not allowed when the governor is set to performance."
                  ),
                self,
            )
        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_profile_changed(self, *args):
        """Callback for profile combobox
        Change profile and enable apply_btn
        """
        # pylint: disable=W0612,W0613
        if self.refreshing:
            return
        mod = self.profile_box.get_model()
        profile = mod[self.profile_box.get_selected_index()]
        # Update store
        self.profile = profile.name
        self._set_profile_settings(profile)
        self.upd_sliders()
        self.apply_btn.set_sensitive(self.is_conf_changed)

    @Gtk.Template.Callback()
    def on_apply_clicked(self, button):
        """Write changes back to sysfs"""
        ret = -1
        cpu = self._get_active_cpu()
        conf = self.settings[cpu]
        fmin, fmax = conf.freqs_scaled
        gov = conf.governor
        pref = conf.energy_pref

        if not HELPER.isauthorized():
            error_message(
                _("You don't have permissions to update cpu settings!"), self)

        # Update only the cpus whose settings were changed
        changed_cpus = [
            cpu for cpu, conf in self.settings.items() if conf.changed
        ]
        for cpu in changed_cpus:
            conf = self.settings.get(cpu)
            cpu_online = conf.online
            ret = self.set_cpu_online(cpu)
            if cpu_online:
                if conf.setting_changed("freqs"):
                    ret += self.set_cpu_frequencies(cpu)
                if conf.setting_changed("governor"):
                    ret += self.set_cpu_governor(cpu)
                if conf.setting_changed("energy_pref"):
                    ret += self.set_cpu_energy_preferences(cpu)

        for cpu in self.settings.keys():
            self._refresh_cpu_settings(cpu)

        # Update sliders
        self.profile_box.set_selected_index(0)

        self.load_cpu_settings()
        self.upd_sliders()

        if ret == 0:
            button.set_sensitive(False)
        else:
            error = ERRORS[ret]
            error_message(error, self)

    def on_prof_name_changed(self, entry, button):
        """Checks if there is text in entry"""
        if self.profile_name_entry.get_text() != "":
            button.set_sensitive(True)
        else:
            button.set_sensitive(False)

    def on_save_profile_clicked(self, button):
        """Callback saving the profile"""
        name = self.profile_name_entry.get_text().strip()
        self.conf.create_profile_from_settings(name, self.settings)
        self.profiles = self.conf.profiles
        self.update_profile_boxes()
        self.update_profiles_page()
        self.profile_name_entry.set_text("")

    def on_delete_profile_clicked(self, button, profile):
        """Callback for about"""
        message = Gtk.MessageDialog(
            transient_for=self,
            type=Gtk.MessageType.QUESTION,
            buttons=Gtk.ButtonsType.OK_CANCEL,
            text=_("Are you sure sure you want to delete this profile?"),
        )
        response = message.run()
        if response == Gtk.ResponseType.OK:
            self.conf.delete_profile(profile)
            self.profiles = self.conf.profiles
            self.update_profile_boxes()
            self.update_profiles_page()
        message.destroy()

    @Gtk.Template.Callback()
    def on_about_clicked(self, button):
        """Callback for about"""
        self.show_about_dialog()

    def show_about_dialog(self):
        """Shows the about dialog"""
        self.about_dialog.run()
        self.about_dialog.hide()

    @property
    def online_cpus(self):
        """Convenience function to get a list of available CPUs"""
        avail = HELPER.get_cpus_available()
        if avail:
            return [int(cpu) for cpu in avail]
        return avail

    @property
    def is_conf_changed(self):
        """Helper function to check if settings were changed"""
        changed = [cpu for cpu, conf in self.settings.items() if conf.changed]
        return len(changed) > 0

    @staticmethod
    def is_online(cpu):
        """Wrapper to get the online state for a cpu

        Args:
            cpu: Index of cpu to query

        Returns:
            bool: True if cpu is online, false otherwise

        """

        online = HELPER.get_cpus_online()
        present = HELPER.get_cpus_present()
        return (cpu in present) and (cpu in online)

    @staticmethod
    def is_offline(cpu):
        """Wrapper to get the online state for a cpu

        Args:
            cpu: Index of cpu to query

        Returns:
            bool: True if cpu is offline, false otherwise

        """
        offline = HELPER.get_cpus_offline()
        present = HELPER.get_cpus_present()
        return (cpu in present) and (cpu in offline)

    @staticmethod
    def get_cpu_governors(cpu):
        """Wrapper to get the list of available governors for a cpu

        Args:
            cpu: Index of cpu to query

        """
        governors = []
        for gov in HELPER.get_cpu_governors(cpu):
            governors.append(str(gov))

        return governors

    @staticmethod
    def get_cpu_frequency_steps(cpu):
        """Wrapper to get the list of available frequencies

        Args:
            cpu: Index of cpu to query

        """
        frequencies = read_available_frequencies(cpu)
        if not frequencies:
            return []

        # Convert and scale frequencies to MHz
        return [int(freq) / 1e3 for freq in frequencies]

    @staticmethod
    def conv_float(col, cell, model, treeiter, data):
        """Helper function to convert float to string with 2 decimal digits"""
        val = model.get(treeiter, data)[0]
        cell.set_property("text", "{:.2f}".format(val))

    def set_cpu_online(self, cpu):
        """Sets the online attribute for cpu

        Args:
            cpu: Index of cpu to set

        """
        conf = self.settings.get(cpu)
        if conf is None:
            return

        cpu_online = conf.online

        # If cpu is offline, enable and update freq settings
        if self.is_offline(cpu) and cpu_online:
            ret = HELPER.set_cpu_online(cpu)
            self.upd_sliders()
            return ret

        # If cpu is online, disable
        if self.is_online(cpu) and not cpu_online:
            # Set offline only if CPU is allowed to go offline
            if HELPER.cpu_allowed_offline(cpu):
                return HELPER.set_cpu_offline(cpu)

        # No change to the cpu
        return 0

    def set_cpu_governor(self, cpu):
        """Sets the governor for cpu

        Args:
            cpu: Index of cpu to set

        """
        ret = -1
        conf = self.settings.get(cpu)
        if conf is None:
            return ret

        gov = conf.governor
        # If govid is None means that there is an error with the kernel
        # https://github.com/vagnum08/cpupower-gui/issues/12
        if gov is None:
            return ret

        ret = HELPER.update_cpu_governor(cpu, gov)

        if ret != 0:
            return -11
        return ret

    def set_cpu_energy_preferences(self, cpu):
        """Sets the energy performance preference for cpu

        Args:
            cpu: Index of cpu to set

        """

        # Return success if not available
        if not self.energy_pref_avail:
            return 0

        ret = -1
        conf = self.settings.get(cpu)
        if conf is None:
            return ret

        pref = conf.energy_pref
        if not pref:
            return ret

        ret = HELPER.update_cpu_energy_prefs(cpu, pref)

        if ret != 0:
            return -12
        return ret

    def set_cpu_frequencies(self, cpu):
        """Sets the frequency limits for cpu

        Args:
            cpu: Index of cpu to set

        """
        ret = -1
        conf = self.settings.get(cpu)
        if conf is None:
            return ret

        fmin, fmax = conf.freqs_scaled
        if (fmin is not None) and (fmax is not None):
            ret = HELPER.update_cpu_settings(cpu, fmin, fmax)
        if ret != 0:
            return -13
        return ret
Ejemplo n.º 30
0
class HeaderBar(Handy.HeaderBar):
    __gtype_name__ = 'HeaderBar'

    __gsignals__ = {
        'tarajem-toggled': (GObject.SIGNAL_RUN_CLEANUP, None, ()),
        'mobileview-toggled': (GObject.SIGNAL_RUN_CLEANUP, None, ())}

    Handy.init()

    squeezer = Gtk.Template.Child()
    headerbar_switcher = Gtk.Template.Child()
    button_open_search = Gtk.Template.Child()
    button_open_tarajem = Gtk.Template.Child()
    button_tarajem_option = Gtk.Template.Child()
    button_telaawa_playback = Gtk.Template.Child()
    icon_telaawa_playback = Gtk.Template.Child()
    button_telaawa_option = Gtk.Template.Child()
    button_open_mainmenu = Gtk.Template.Child()

    window_title = Gtk.Template.Child()
    window_title_alt = Gtk.Template.Child()

    button_open_navigation = Gtk.Template.Child()
    button_open_navigation_alt = Gtk.Template.Child()

    is_updating: bool = False  # to prevent unwanted widget triggering

    def __init__(
            self,
            **kwargs) -> None:
        super().__init__(**kwargs)

        child = self.squeezer.get_visible_child()
        glob.mobile_view = child != self.headerbar_switcher

        self.setup_tarajem_popover()
        self.setup_navigation_popover()
        self.setup_telaawa_popover()
        self.setup_main_menu()

        # Watch the squeezer when it starts to hide some of its children
        self.squeezer.connect('notify::visible-child', self.on_squeezed)

    def setup_tarajem_popover(self) -> None:
        self.popover_tarajem = TarajemPopover()
        self.button_tarajem_option.set_popover(self.popover_tarajem)

    def setup_navigation_popover(self) -> None:
        self.popover_nav = NavigationPopover(0)
        self.button_open_navigation.set_popover(self.popover_nav)

        self.popover_nav_alt = NavigationPopover(1)
        self.popover_nav_alt.container.set_orientation(
            Gtk.Orientation.VERTICAL)
        self.popover_nav_alt.container.set_spacing(8)
        self.button_open_navigation_alt.set_popover(self.popover_nav_alt)

        # Whenever focused ayah changed, change the window title to the newly
        # selected ayah
        self.popover_nav.connect('change-win-title', self.change_title)
        self.popover_nav_alt.connect('change-win-title', self.change_title)

    def setup_telaawa_popover(self) -> None:
        self.popover_telaawa = TelaawaPopover()
        self.button_telaawa_option.set_popover(self.popover_telaawa)

        self.popover_telaawa.connect('telaawa-playback', self.telaawa_toggled)

    def setup_main_menu(self) -> None:
        self.popover_menu = MainMenu()
        self.button_open_mainmenu.set_popover(self.popover_menu)

    @Gtk.Template.Callback()
    def toggle_tarajem(
            self,
            button: Gtk.ToggleButton) -> None:
        glob.tarajem_visibility = button.get_active()
        self.emit('tarajem-toggled')

    @Gtk.Template.Callback()
    def toggle_telaawa(
            self,
            button: Gtk.ToggleButton) -> None:
        if self.is_updating:
            return

        is_activated = button.get_active()
        if is_activated:
            self.icon_telaawa_playback.set_from_icon_name(
                'media-playback-pause-symbolic', Gtk.IconSize.BUTTON)
        else:
            self.icon_telaawa_playback.set_from_icon_name(
                'media-playback-start-symbolic', Gtk.IconSize.BUTTON)

        button_playback_telaawa = self.popover_telaawa.button_toggle_playback
        button_playback_telaawa.set_active(is_activated)

    def telaawa_toggled(
            self,
            button: Gtk.ToggleButton,
            state: bool) -> None:
        self.is_updating = True
        self.button_telaawa_playback.set_active(state)
        self.is_updating = False

        if state:
            self.icon_telaawa_playback.set_from_icon_name(
                'media-playback-pause-symbolic', Gtk.IconSize.BUTTON)
        else:
            self.icon_telaawa_playback.set_from_icon_name(
                'media-playback-start-symbolic', Gtk.IconSize.BUTTON)

    def on_squeezed(
            self,
            squeezer: Handy.Squeezer,
            event: Gdk.Event) -> None:
        child = squeezer.get_visible_child()
        glob.mobile_view = child != self.headerbar_switcher
        self.emit('mobileview-toggled')

    def change_title(
            self,
            widget: Gtk.Widget,
            title: str) -> None:
        if not glob.mobile_view:
            self.window_title.set_text(title)
        else:
            self.window_title_alt.set_text(title)