Add license UI (#23)
This commit is contained in:
parent
b8e2310461
commit
a7dd9885e1
|
|
@ -43,8 +43,16 @@ else
|
|||
cp $abs_path $tmp_dir
|
||||
fi
|
||||
|
||||
# if abs_path is present, grab the filename from it
|
||||
if [ -n "$abs_path" ]
|
||||
then
|
||||
filename=$(basename $abs_path)
|
||||
else
|
||||
filename="breezyGNOME.tar.gz"
|
||||
fi
|
||||
|
||||
echo "Extracting to: ${tmp_dir}/breezy_gnome"
|
||||
tar -xf breezyGNOME.tar.gz
|
||||
tar -xf $filename
|
||||
|
||||
pushd breezy_gnome > /dev/null
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit f379c976e003823ed6a61fe2d054c802b3bca80d
|
||||
Subproject commit 8e5513c89df30ca2cfdcd03947dcb8d9562db6b3
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit b2cdc8cc5fc593ab04015cec08a8e97b103ffa63
|
||||
Subproject commit 831a31d3b8ac74964be5506b4cd9b81f6755d634
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
<gresources>
|
||||
<gresource prefix="/com/xronlinux/BreezyDesktop">
|
||||
<file preprocess="xml-stripblanks">gtk/connected-device.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/license-dialog.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/no-device.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/no-extension.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/shortcut-dialog.ui</file>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<property name="column-spacing">4</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="device_label">
|
||||
<property name="label">VITURE One</property>
|
||||
<property name="label"></property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<template class="LicenseDialog" parent="GtkDialog">
|
||||
<property name="title">License Details</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="default_width">440</property>
|
||||
<property name="default_height">200</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="refresh_license_button">
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-start">20</property>
|
||||
<property name="margin-end">20</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="margin-top">10</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Donate</property>
|
||||
<property name="subtitle" translatable="true">ko-fi.com/wheaney</property>
|
||||
<property name="subtitle-selectable">True</property>
|
||||
<child type="suffix">
|
||||
<object class="GtkLinkButton">
|
||||
<property name="icon-name">go-next-symbolic</property>
|
||||
<property name="uri">https://ko-fi.com/wheaney</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwEntryRow" id="request_token">
|
||||
<property name="visible">0</property>
|
||||
<property name="title" translatable="true">Request a token</property>
|
||||
<property name="input-purpose">6</property>
|
||||
<property name="show-apply-button">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwEntryRow" id="verify_token">
|
||||
<property name="visible">0</property>
|
||||
<property name="title" translatable="true">Verify token</property>
|
||||
<property name="input-hints">16</property>
|
||||
<property name="show-apply-button">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="tiers">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="features">
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<template class="ShortcutDialog" parent="GtkDialog">
|
||||
<property name="title">Assign Keyboard Shortcut</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="default_width">440</property>
|
||||
<property name="default_height">200</property>
|
||||
|
|
@ -21,23 +22,8 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="title-widget">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Keyboard Shortcut</property>
|
||||
<property name="single-line-mode">1</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="width-chars">5</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventControllerKey" id="event_controller" />
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
</interface>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,28 @@
|
|||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="AdwBanner" id="license_action_needed_banner">
|
||||
<property name="revealed">0</property>
|
||||
<property name="title" translatable="yes">Some features expire soon</property>
|
||||
<property name="button-label" translatable="yes">View details</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_content" />
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
<menu id="primary_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">License Details</attribute>
|
||||
<attribute name="action">app.license</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About BreezyDesktop</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
from gi.repository import Adw, Gtk, GLib
|
||||
from .statemanager import StateManager
|
||||
from .licensetierrow import LicenseTierRow
|
||||
from .licensefeaturerow import LicenseFeatureRow
|
||||
from .xrdriveripc import XRDriverIPC
|
||||
|
||||
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/license-dialog.ui')
|
||||
class LicenseDialog(Gtk.Dialog):
|
||||
__gtype_name__ = 'LicenseDialog'
|
||||
|
||||
tiers = Gtk.Template.Child()
|
||||
features = Gtk.Template.Child()
|
||||
request_token = Gtk.Template.Child()
|
||||
verify_token = Gtk.Template.Child()
|
||||
refresh_license_button = Gtk.Template.Child()
|
||||
|
||||
def __init__(self):
|
||||
super(Gtk.Dialog, self).__init__()
|
||||
self.init_template()
|
||||
|
||||
self.ipc = XRDriverIPC.get_instance()
|
||||
StateManager.get_instance().connect('license-action-needed', self._handle_license)
|
||||
self._handle_license(StateManager.get_instance())
|
||||
|
||||
self.request_token.connect('apply', self._on_request_token)
|
||||
self.verify_token.connect('apply', self._on_verify_token)
|
||||
self.refresh_license_button.connect('clicked', self._refresh_license)
|
||||
|
||||
def _refresh_license(self, widget):
|
||||
self.refresh_license_button.set_sensitive(False)
|
||||
self.ipc.write_control_flags({'refresh_device_license': True})
|
||||
GLib.timeout_add_seconds(3, self._handle_license)
|
||||
|
||||
def _handle_license(self, state_manager = None, val = None):
|
||||
GLib.idle_add(self._handle_license_idle, state_manager or StateManager.get_instance())
|
||||
|
||||
def _handle_license_idle(self, state_manager):
|
||||
self.refresh_license_button.set_sensitive(False)
|
||||
|
||||
license_view = state_manager.state['ui_view']['license']
|
||||
self.request_token.set_visible(not state_manager.confirmed_token)
|
||||
self.verify_token.set_visible(not state_manager.confirmed_token)
|
||||
|
||||
for child in self.tiers:
|
||||
self.tiers.remove(child)
|
||||
tiers_group = Adw.PreferencesGroup(title="Paid Tier Status", margin_top=20)
|
||||
self.tiers.append(tiers_group)
|
||||
|
||||
for tier_name, tier_details in license_view['tiers'].items():
|
||||
tiers_group.add(LicenseTierRow(tier_name, tier_details))
|
||||
|
||||
for child in self.features:
|
||||
self.features.remove(child)
|
||||
features_group = Adw.PreferencesGroup(title="Feature Availability", margin_top=20)
|
||||
self.features.append(features_group)
|
||||
|
||||
for feature_name, feature_details in license_view['features'].items():
|
||||
features_group.add(LicenseFeatureRow(feature_name, feature_details))
|
||||
|
||||
self.refresh_license_button.set_sensitive(True)
|
||||
|
||||
def _on_request_token(self, widget):
|
||||
email_address = self.request_token.get_text()
|
||||
self.request_token.set_editable(False)
|
||||
if not self.ipc.request_token(email_address):
|
||||
self.request_token.set_editable(True)
|
||||
|
||||
def _on_verify_token(self, widget):
|
||||
token = self.verify_token.get_text()
|
||||
self.request_token.set_editable(False)
|
||||
self.verify_token.set_editable(False)
|
||||
if self.ipc.verify_token(token):
|
||||
self.ipc.write_control_flags({'refresh_device_license': True})
|
||||
else:
|
||||
self.request_token.set_editable(True)
|
||||
self.verify_token.set_editable(True)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
from gi.repository import Adw, Gtk
|
||||
|
||||
from .time import time_remaining_text
|
||||
|
||||
FEATURE_NAMES = {
|
||||
'sbs': 'Side-by-side mode (for gaming)',
|
||||
'smooth_follow': 'Smooth Follow',
|
||||
'productivity_basic': 'Breezy Desktop',
|
||||
'productivity_pro': 'Breezy Desktop w/ multiple monitors',
|
||||
}
|
||||
|
||||
class LicenseFeatureRow(Adw.ActionRow):
|
||||
|
||||
def __init__(self, feature, feature_details):
|
||||
super().__init__()
|
||||
|
||||
self.set_title(FEATURE_NAMES[feature])
|
||||
|
||||
status = 'Disabled'
|
||||
is_trial = feature_details.get('is_trial') == True
|
||||
if feature_details.get('is_enabled') == True:
|
||||
status = 'In trial' if is_trial else 'Enabled'
|
||||
|
||||
details = ''
|
||||
funds_needed_in_seconds = feature_details.get('funds_needed_in_seconds')
|
||||
if funds_needed_in_seconds is not None and funds_needed_in_seconds > 0:
|
||||
time_remaining = time_remaining_text(funds_needed_in_seconds, is_trial)
|
||||
if time_remaining: details = f" ({time_remaining} remaining)"
|
||||
|
||||
self.set_subtitle(f"{status}{details}")
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
from gi.repository import Adw, Gtk
|
||||
|
||||
from .time import time_remaining_text
|
||||
|
||||
TIER_NAMES = {
|
||||
'supporter': 'Gaming',
|
||||
'subscriber': 'Productivity',
|
||||
'subscriber_pro': 'Productivity Pro',
|
||||
}
|
||||
|
||||
PERIOD_DESCRIPTIONS = {
|
||||
'monthly': ' - renewing monthly',
|
||||
'yearly': ' - renewing yearly',
|
||||
'lifetime': 'with lifetime access',
|
||||
}
|
||||
|
||||
PERIOD_RANKS = {
|
||||
'monthly': 1,
|
||||
'yearly': 2,
|
||||
'lifetime': 3,
|
||||
}
|
||||
|
||||
class LicenseTierRow(Adw.ExpanderRow):
|
||||
|
||||
def __init__(self, tier, tier_details):
|
||||
super().__init__()
|
||||
|
||||
self.set_title(TIER_NAMES[tier])
|
||||
|
||||
active_period = tier_details.get('active_period')
|
||||
funds_needed_in_seconds = tier_details.get('funds_needed_in_seconds')
|
||||
|
||||
status = 'Active' if active_period else 'Inactive'
|
||||
details = ''
|
||||
if active_period:
|
||||
details += f" {PERIOD_DESCRIPTIONS[active_period]}"
|
||||
if funds_needed_in_seconds is not None and funds_needed_in_seconds > 0:
|
||||
time_remaining = time_remaining_text(funds_needed_in_seconds)
|
||||
if time_remaining: details += f" ({time_remaining} remaining)"
|
||||
if active_period == 'lifetime':
|
||||
self.set_enable_expansion(False)
|
||||
self.set_icon_name(None)
|
||||
|
||||
self.set_expanded(False)
|
||||
self.set_subtitle(f"{status}{details}")
|
||||
|
||||
for period, amount in tier_details['funds_needed_by_period'].items():
|
||||
amount_text = None
|
||||
if amount > 0:
|
||||
amount_text = f"<b>${amount}</b> USD"
|
||||
if active_period == period:
|
||||
amount_text += " to renew"
|
||||
elif active_period is not None:
|
||||
amount_text += " to upgrade"
|
||||
elif active_period is not None and PERIOD_RANKS[period] >= PERIOD_RANKS[active_period]:
|
||||
amount_text = "Ready to auto-renew"
|
||||
|
||||
if amount_text is not None:
|
||||
row_widget = Adw.ActionRow(title=period.capitalize())
|
||||
row_widget.add_suffix(Gtk.Label(label=amount_text, use_markup=True))
|
||||
self.add_row(row_widget)
|
||||
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ gi.require_version('Adw', '1')
|
|||
gi.require_version('Gio', '2.0')
|
||||
|
||||
from gi.repository import Adw, Gtk, Gio
|
||||
from .licensedialog import LicenseDialog
|
||||
from .statemanager import StateManager
|
||||
from .window import BreezydesktopWindow
|
||||
|
||||
|
|
@ -36,6 +37,7 @@ class BreezydesktopApplication(Adw.Application):
|
|||
flags=Gio.ApplicationFlags.DEFAULT_FLAGS)
|
||||
self.create_action('quit', self.on_quit_action, ['<primary>q'])
|
||||
self.create_action('about', self.on_about_action)
|
||||
self.create_action('license', self.on_license_action)
|
||||
|
||||
def do_activate(self):
|
||||
"""Called when the application is activated.
|
||||
|
|
@ -61,6 +63,11 @@ class BreezydesktopApplication(Adw.Application):
|
|||
copyright='© 2024 Wayne Heaney')
|
||||
about.present()
|
||||
|
||||
def on_license_action(self, widget, _):
|
||||
dialog = LicenseDialog()
|
||||
dialog.set_transient_for(self.props.active_window)
|
||||
dialog.present()
|
||||
|
||||
def create_action(self, name, callback, shortcuts=None):
|
||||
"""Add an application action.
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,16 @@ breezydesktop_sources = [
|
|||
'__init__.py',
|
||||
'connecteddevice.py',
|
||||
'extensionsmanager.py',
|
||||
'licensedialog.py',
|
||||
'licensefeaturerow.py',
|
||||
'licensetierrow.py',
|
||||
'main.py',
|
||||
'nodevice.py',
|
||||
'noextension.py',
|
||||
'settingsmanager.py',
|
||||
'shortcutdialog.py',
|
||||
'statemanager.py',
|
||||
'time.py',
|
||||
'window.py'
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import sys
|
||||
import threading
|
||||
from gi.repository import GObject
|
||||
from .time import LICENSE_WARN_SECONDS
|
||||
from .xrdriveripc import XRDriverIPC
|
||||
|
||||
# shouldn't need a number larger than a year
|
||||
LICENSE_ACTION_NEEDED_MAX = 60 * 60 * 24 * 366
|
||||
|
||||
class Logger:
|
||||
def info(self, message):
|
||||
print(message)
|
||||
|
|
@ -11,11 +16,13 @@ class Logger:
|
|||
|
||||
class StateManager(GObject.GObject):
|
||||
__gsignals__ = {
|
||||
'device-update': (GObject.SIGNAL_RUN_FIRST, None, (str,))
|
||||
'device-update': (GObject.SIGNAL_RUN_FIRST, None, (str,)),
|
||||
'license-action-needed': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
|
||||
}
|
||||
|
||||
__gproperties__ = {
|
||||
'follow-mode': (bool, 'Follow Mode', 'Whether the follow mode is enabled', False, GObject.ParamFlags.READWRITE)
|
||||
'follow-mode': (bool, 'Follow Mode', 'Whether the follow mode is enabled', False, GObject.ParamFlags.READWRITE),
|
||||
'license-action-needed-seconds': (int, 'License Action Needed Seconds', 'The remaining time until the license action is needed', 0, LICENSE_ACTION_NEEDED_MAX, 0, GObject.ParamFlags.READWRITE),
|
||||
}
|
||||
|
||||
_instance = None
|
||||
|
|
@ -44,6 +51,9 @@ class StateManager(GObject.GObject):
|
|||
GObject.GObject.__init__(self)
|
||||
self.ipc = XRDriverIPC.get_instance()
|
||||
self.connected_device_name = None
|
||||
self.license_action_needed = False
|
||||
self.license_action_needed_seconds = 0
|
||||
self.confirmed_token = False
|
||||
|
||||
self.start()
|
||||
|
||||
|
|
@ -61,14 +71,32 @@ class StateManager(GObject.GObject):
|
|||
self.connected_device_name = new_device_name
|
||||
self.emit('device-update', self.connected_device_name)
|
||||
|
||||
license_view = self.state['ui_view'].get('license')
|
||||
if license_view:
|
||||
confirmed_token = license_view.get('confirmed_token') == True
|
||||
action_needed_details = license_view.get('action_needed')
|
||||
action_needed_seconds = action_needed_details.get('seconds') if action_needed_details else None
|
||||
|
||||
action_needed = action_needed_seconds is not None and action_needed_seconds < LICENSE_WARN_SECONDS
|
||||
if (action_needed != self.license_action_needed or self.confirmed_token != confirmed_token):
|
||||
self.license_action_needed = action_needed
|
||||
self.license_action_needed_seconds = action_needed_seconds
|
||||
self.confirmed_token = confirmed_token
|
||||
self.emit('license-action-needed', action_needed or not confirmed_token)
|
||||
|
||||
self.set_property('follow-mode', self.state.get('breezy_desktop_smooth_follow_enabled'))
|
||||
self.set_property('license-action-needed-seconds', self.license_action_needed_seconds)
|
||||
|
||||
if self.running: threading.Timer(1.0, self._refresh_state).start()
|
||||
|
||||
def do_set_property(self, prop, value):
|
||||
if prop.name == 'follow-mode':
|
||||
self.follow_mode = value
|
||||
if prop.name == 'license-action-needed-seconds':
|
||||
self.license_action_needed_seconds = value
|
||||
|
||||
def do_get_property(self, prop):
|
||||
if prop.name == 'follow-mode':
|
||||
return self.follow_mode
|
||||
return self.follow_mode
|
||||
if prop.name == 'license-action-needed-seconds':
|
||||
return self.license_action_needed_seconds
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from math import floor
|
||||
|
||||
# we'll begin to alert the user when there's less than a week left
|
||||
LICENSE_WARN_SECONDS = 60 * 60 * 24 * 7
|
||||
|
||||
def time_remaining_text(seconds, no_cap=False):
|
||||
if not seconds:
|
||||
return
|
||||
|
||||
if seconds / 60 < 60:
|
||||
return 'less than an hour'
|
||||
elif seconds / (60 * 60) < 24:
|
||||
time_remaining = floor(seconds / (60 * 60))
|
||||
return '1 hour' if time_remaining == 1 else f'{time_remaining} hours'
|
||||
elif seconds / (24 * 60 * 60) < 30 or no_cap:
|
||||
time_remaining = floor(seconds / (24 * 60 * 60))
|
||||
return '1 day' if time_remaining == 1 else f'{time_remaining} days'
|
||||
else:
|
||||
return
|
||||
|
|
@ -17,39 +17,62 @@
|
|||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gtk, GLib
|
||||
from .extensionsmanager import ExtensionsManager
|
||||
from .licensedialog import LicenseDialog
|
||||
from .statemanager import StateManager
|
||||
from .connecteddevice import ConnectedDevice
|
||||
from .nodevice import NoDevice
|
||||
from .noextension import NoExtension
|
||||
from .time import LICENSE_WARN_SECONDS
|
||||
|
||||
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/window.ui')
|
||||
class BreezydesktopWindow(Gtk.ApplicationWindow):
|
||||
__gtype_name__ = 'BreezydesktopWindow'
|
||||
|
||||
main_content = Gtk.Template.Child()
|
||||
license_action_needed_banner = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.state_manager = StateManager.get_instance()
|
||||
self.state_manager.connect('device-update', self._handle_device_update)
|
||||
self.state_manager.connect('license-action-needed', self._handle_device_update)
|
||||
|
||||
self.connected_device = ConnectedDevice()
|
||||
self.no_device = NoDevice()
|
||||
self.no_extension = NoExtension()
|
||||
|
||||
self._handle_device_update(self.state_manager, StateManager.device_name(self.state_manager.state))
|
||||
self.license_action_needed_banner.connect('button-clicked', self._on_license_action_needed_button_clicked)
|
||||
|
||||
self._handle_device_update(self.state_manager, None)
|
||||
|
||||
self.connect("destroy", self._on_window_destroy)
|
||||
|
||||
def _handle_device_update(self, state_manager, connected_device_name):
|
||||
def _handle_device_update(self, state_manager, val):
|
||||
GLib.idle_add(self._handle_device_update_gui, state_manager)
|
||||
|
||||
def _handle_device_update_gui(self, state_manager):
|
||||
license_action_needed_seconds = state_manager.get_property('license-action-needed-seconds')
|
||||
show_banner = license_action_needed_seconds is not None and license_action_needed_seconds < LICENSE_WARN_SECONDS
|
||||
self.license_action_needed_banner.set_revealed(show_banner)
|
||||
|
||||
for child in self.main_content:
|
||||
self.main_content.remove(child)
|
||||
|
||||
if not ExtensionsManager.get_instance().is_installed():
|
||||
self.set_child(self.no_extension)
|
||||
elif connected_device_name:
|
||||
self.set_child(self.connected_device)
|
||||
self.connected_device.set_device_name(connected_device_name)
|
||||
self.main_content.append(self.no_extension)
|
||||
elif state_manager.connected_device_name:
|
||||
self.main_content.append(self.connected_device)
|
||||
self.connected_device.set_device_name(state_manager.connected_device_name)
|
||||
else:
|
||||
self.set_child(self.no_device)
|
||||
self.main_content.append(self.no_device)
|
||||
|
||||
def _on_license_action_needed_button_clicked(self, widget):
|
||||
dialog = LicenseDialog()
|
||||
dialog.set_transient_for(widget.get_ancestor(Gtk.Window))
|
||||
dialog.present()
|
||||
|
||||
def _on_window_destroy(self, widget):
|
||||
self.state_manager.disconnect_by_func(self._handle_device_update)
|
||||
Loading…
Reference in New Issue