251 lines
11 KiB
Python
251 lines
11 KiB
Python
import logging
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
from gi.repository import Gtk, Pango
|
|
from ks_includes.screen_panel import ScreenPanel
|
|
|
|
|
|
class Panel(ScreenPanel):
|
|
|
|
def __init__(self, screen, title, **kwargs):
|
|
title = title or _("license")
|
|
super().__init__(screen, title)
|
|
self.title_text = (
|
|
_("This device is not activated and is available for trial use only")
|
|
+ "\n"
|
|
+ _("Please enter a key to activate")
|
|
)
|
|
self.key_len = 15
|
|
self.key_val_test = 1
|
|
self.key_val_add = 2
|
|
self.key_val_minus = 3
|
|
self.full = False
|
|
self.interface = screen.license
|
|
self.serial_num = self.interface.get_unique_id() or _("Unknown")
|
|
self.is_active = self.interface.is_active()
|
|
self.args = {}
|
|
|
|
def update_time(self):
|
|
total_printed_time = max(0, self.interface.get_total_printed_time())
|
|
trial_time = max(0, self.interface.get_trial_time())
|
|
remaining_time = max(0, trial_time - total_printed_time)
|
|
|
|
self.license_box["elapsed_trial_time_value"].set_text(self.seconds_to_hms(total_printed_time))
|
|
self.license_box["trial_time_value"].set_text(self.seconds_to_hms(trial_time))
|
|
self.license_box["remain_time_value"].set_text(self.seconds_to_hms(remaining_time))
|
|
|
|
def seconds_to_hms(self, seconds):
|
|
|
|
if not isinstance(seconds, (int, float)) or seconds < 0:
|
|
raise ValueError(f"seconds must be a non-negative number, got {seconds}")
|
|
|
|
hours, remainder = divmod(int(seconds), 3600)
|
|
minutes, secs = divmod(remainder, 60)
|
|
|
|
return f"{hours:03}:{minutes:02}:{secs:02}"
|
|
|
|
def state_update(self, text):
|
|
self.license_box["state_text_value"].set_text(text)
|
|
|
|
def verify_key(self, key):
|
|
try:
|
|
res = self.interface.verify_activation_code(key)
|
|
if res:
|
|
if self.interface.is_active():
|
|
self.is_active = True
|
|
self.state_update(_("Permanent Activation"))
|
|
else:
|
|
self.state_update(_("Key is valid"))
|
|
else:
|
|
self.state_update(_("Key is invalid"))
|
|
except Exception as e:
|
|
logging.exception(e)
|
|
|
|
def active_refresh(self, **args):
|
|
self.args["full"] = args.get("full")
|
|
self.args["callback"] = args.get("func")
|
|
self.args["file"] = args.get("file")
|
|
self.args["onboarding"] = args.get("onboarding")
|
|
self.display_dialog()
|
|
|
|
def deactivate(self):
|
|
self._screen.remove_keyboard()
|
|
for child in self.content.get_children():
|
|
self.content.remove(child)
|
|
|
|
def display_test_dialog(self, key_text=""):
|
|
buttons = [
|
|
{"name": _("Add"), "response": self.key_val_add, "style": "dialog-secondary"},
|
|
{"name": _("Minus"), "response": self.key_val_minus, "style": "dialog-info"},
|
|
{"name": _("Close"), "response": Gtk.ResponseType.CLOSE, "style": "dialog-error"},
|
|
]
|
|
self.create_license_key_dialog(buttons=buttons, key=key_text)
|
|
def display_dialog(self, full=False, key=""):
|
|
BUTTON_CONFIGS = {
|
|
"trial_with_callback": [
|
|
{"name": _("Activate"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
|
{"name": _("Skip"), "response": Gtk.ResponseType.CANCEL, "style": "dialog-error"},
|
|
],
|
|
"full_features": [
|
|
{"name": _("Test Mode"), "response": self.key_val_test, "style": "dialog-secondary"},
|
|
{"name": _("Activate"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
|
{"name": _("Close"), "response": Gtk.ResponseType.CLOSE, "style": "dialog-error"},
|
|
],
|
|
"Trial": [
|
|
{"name": _("Activate"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
|
{"name": _("Trial"), "response": Gtk.ResponseType.CLOSE, "style": "dialog-error"},
|
|
],
|
|
"default": [
|
|
{"name": _("Activate"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
|
{"name": _("Close"), "response": Gtk.ResponseType.CLOSE, "style": "dialog-error"},
|
|
],
|
|
}
|
|
|
|
if self.args.get("callback") and self.interface.is_trial_active():
|
|
buttons = BUTTON_CONFIGS["trial_with_callback"]
|
|
elif self.args.get("full"):
|
|
buttons = BUTTON_CONFIGS["full_features"]
|
|
elif self.args.get("onboarding"):
|
|
buttons = BUTTON_CONFIGS["Trial"]
|
|
else:
|
|
buttons = BUTTON_CONFIGS["default"]
|
|
|
|
self.create_license_key_dialog(buttons=buttons, key=key)
|
|
|
|
def create_license_key_dialog(self, buttons=None, key=""):
|
|
|
|
if buttons is None:
|
|
buttons = [
|
|
{"name": _("Activate"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
|
{"name": _("Close"), "response": Gtk.ResponseType.CLOSE, "style": "dialog-error"},
|
|
]
|
|
|
|
self.title_label = Gtk.Label(hexpand=True, vexpand=False, wrap=True, wrap_mode=Pango.WrapMode.WORD_CHAR)
|
|
self.title_label.set_markup(f"<big>{self.title_text}</big>\n")
|
|
self.title_label.set_margin_top(50)
|
|
self.title_label.set_margin_start(20)
|
|
self.title_label.set_halign(Gtk.Align.START)
|
|
|
|
self.license_box = {}
|
|
|
|
self.grid = Gtk.Grid(column_spacing=20, row_spacing=20, hexpand=True, vexpand=True)
|
|
|
|
def add_labeled_value(row, label_text, value_text):
|
|
label = Gtk.Label(label=label_text, use_markup=True, xalign=0, wrap=True)
|
|
value = Gtk.Label(label=value_text, use_markup=True, xalign=0, wrap=True)
|
|
self.grid.attach(label, 0, row, 1, 1)
|
|
self.grid.attach(value, 1, row, 1, 1)
|
|
return label, value
|
|
|
|
status_text = _("Not activated")
|
|
if not self.interface.is_interface_valid():
|
|
status_text = _("Unknown")
|
|
elif self.is_active:
|
|
status_text = _("Permanent Activation")
|
|
self.title_label.set_markup(f"<big>{status_text}</big>\n")
|
|
self.license_box["state_text"], self.license_box["state_text_value"] = add_labeled_value(
|
|
0, _("State:"), status_text
|
|
)
|
|
self.license_box["serial_num_text"], self.license_box["serial_num_value"] = add_labeled_value(
|
|
1, _("Serial Number:"), self.serial_num
|
|
)
|
|
self.license_box["trial_time_text"], self.license_box["trial_time_value"] = add_labeled_value(
|
|
2, _("Trial Time:"), "000:00:00"
|
|
)
|
|
self.license_box["elapsed_trial_time_text"], self.license_box["elapsed_trial_time_value"] = add_labeled_value(
|
|
3, _("Elapsed trial time:"), "000:00:00"
|
|
)
|
|
self.license_box["remain_time_text"], self.license_box["remain_time_value"] = add_labeled_value(
|
|
4, _("Remaining Time:"), "000:00:00"
|
|
)
|
|
|
|
self.license_box["key_text"] = Gtk.Label(label=_("Key:"), use_markup=True, xalign=0, wrap=True)
|
|
self.grid.attach(self.license_box["key_text"], 0, 5, 1, 1)
|
|
|
|
self.license_box["key_input"] = Gtk.Entry(hexpand=False, vexpand=False)
|
|
self.license_box["key_input"].set_max_length(self.key_len)
|
|
self.license_box["key_input"].set_text(key)
|
|
self.license_box["key_input"].connect("button-press-event", self.on_show_keyboard)
|
|
self.grid.attach(self.license_box["key_input"], 1, 5, 1, 1)
|
|
|
|
image = self._gtk.Image("license", self._gtk.content_width * 0.4, self._gtk.content_height * 0.4)
|
|
image.set_margin_start(60)
|
|
image.set_margin_end(20)
|
|
|
|
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, vexpand=True)
|
|
horizontal_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, vexpand=True)
|
|
horizontal_box.set_margin_top(20)
|
|
|
|
self.grid.set_margin_start(60)
|
|
horizontal_box.pack_start(image, False, True, 0)
|
|
horizontal_box.pack_start(self.grid, True, True, 0)
|
|
|
|
main_box.pack_start(self.title_label, False, True, 0)
|
|
main_box.pack_start(horizontal_box, True, True, 0)
|
|
|
|
self.dialog = self._gtk.Dialog("License", buttons, main_box, self.confirm_license_response)
|
|
self.update_time()
|
|
|
|
def confirm_license_response(self, dialog, response_id):
|
|
if response_id == Gtk.ResponseType.YES:
|
|
if self.interface.enabled_registration():
|
|
self.state_update(_("Enabled successfully"))
|
|
elif response_id == Gtk.ResponseType.CLOSE:
|
|
self._gtk.remove_dialog(dialog)
|
|
self._screen._menu_go_back()
|
|
elif response_id == Gtk.ResponseType.CANCEL:
|
|
self._gtk.remove_dialog(dialog)
|
|
self._screen._menu_go_back()
|
|
if not self.interface.is_active() and self.interface.is_trial_active():
|
|
if self.args.get("callback"):
|
|
self.args["callback"](self.args["file"])
|
|
elif response_id == Gtk.ResponseType.OK:
|
|
if len(self.license_box["key_input"].get_text()) == 0:
|
|
self.state_update(_("Key is empty"))
|
|
return
|
|
self.verify_key(self.license_box["key_input"].get_text())
|
|
self.update_time()
|
|
elif response_id == self.key_val_test:
|
|
if len(self.license_box["key_input"].get_text()) == 0:
|
|
self.state_update(_("Key is empty"))
|
|
return
|
|
if self.interface.test_registration(self.license_box["key_input"].get_text()):
|
|
self._gtk.remove_dialog(dialog)
|
|
self.display_test_dialog()
|
|
else:
|
|
self.state_update(_("Key is invalid"))
|
|
elif response_id == self.key_val_add:
|
|
self.interface.add_registration_time()
|
|
self.update_time()
|
|
elif response_id == self.key_val_minus:
|
|
self.interface.minus_registration_time()
|
|
self.update_time()
|
|
|
|
def on_show_keyboard(self, entry=None, event=None):
|
|
self._gtk.remove_dialog(self.dialog)
|
|
lbl = Gtk.Label(_("Please enter a key to activate"), halign=Gtk.Align.START, hexpand=False)
|
|
self.labels["entry"] = Gtk.Entry(hexpand=True)
|
|
self.labels["entry"].set_max_length(self.key_len)
|
|
self.labels["entry"].connect("focus-in-event", self._screen.show_keyboard)
|
|
save = self._gtk.Button("complete", _("Save"), "color3")
|
|
save.set_hexpand(False)
|
|
save.connect("clicked", self.on_save_key)
|
|
input_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
|
input_box.pack_start(self.labels["entry"], True, True, 5)
|
|
input_box.pack_start(save, False, False, 5)
|
|
self.labels["input_box"] = Gtk.Box(
|
|
orientation=Gtk.Orientation.VERTICAL, spacing=5, hexpand=True, vexpand=True, valign=Gtk.Align.CENTER
|
|
)
|
|
self.labels["input_box"].pack_start(lbl, True, True, 5)
|
|
self.labels["input_box"].pack_start(input_box, True, True, 5)
|
|
self.content.add(self.labels["input_box"])
|
|
self.labels["entry"].grab_focus_without_selecting()
|
|
|
|
def on_save_key(self, dialog):
|
|
key_text = self.labels["entry"].get_text()
|
|
self._screen.remove_keyboard()
|
|
for child in self.content.get_children():
|
|
self.content.remove(child)
|
|
self.display_dialog(self.full, key=key_text)
|