def _add(self, _, playlist_entry): playlist_name = playlist_entry.get_text() if playlist_name == 'Kano': confirm = KanoDialog('You can\'t add to the "Kano" playlist', '', {'BACK': {'return_value': True, 'color': 'red'}}, parent_window=self._main_win) confirm.run() return if playlist_name in playlistCollection.collection: confirm = KanoDialog( 'The playlist "{}" already exists!'.format(playlist_name), 'Do you want to add the video to this playlist or try again?', {'USE PLAYLIST': {'return_value': True}, 'TRY AGAIN': {'return_value': False, 'color': 'red'}}, parent_window=self._main_win) response = confirm.run() if not response: return else: playlist = Playlist(playlist_name) playlistCollection.add(playlist) self._return = playlist_name self.destroy()
def apply_changes(self, button, event): # If enter key is pressed or mouse button is clicked if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return: if self.ssh_preference is not is_ssh_enabled(): set_ssh_enabled(self.ssh_preference) old_debug_mode = self.get_stored_debug_mode() new_debug_mode = self.debug_button.get_active() if new_debug_mode == old_debug_mode: logging.Logger().debug('skipping debug mode change') self.win.go_to_home() return if new_debug_mode: # set debug on: logging.set_system_log_level('debug') logging.Logger().info("setting logging to debug") msg = _("Activated") else: # set debug off: logging.set_system_log_level('error') logging.Logger().info("setting logging to error") msg = _("De-activated") kdialog = KanoDialog(_("Debug mode"), msg, parent_window=self.win) kdialog.run() self.kano_button.set_sensitive(False) self.win.go_to_home()
def _show_error_dialog(self, title, description): # TODO: refactor this kdialog = KanoDialog( title, description, parent_window=self.win ) kdialog.run()
def apply_changes(self, button, event): pw_dialog = ParentalPasswordDialog(self.win) if not pw_dialog.verify(): return level = self.parental_level.get_value() set_parental_level(level) # track which parental control level people use track_data('parental-control-level-changed', {'level': level}) if level == 3.0: # If on the highest parental control, prompt user to relaunch # the browser kdialog = KanoDialog( title_text=_("Settings"), description_text=(_("If any browsers are open, please relaunch " \ "them for this setting to take effect")), parent_window=self.win ) kdialog.run() else: # Only reboot for the lower parental controls common.need_reboot = True self.win.go_to_home()
def apply_changes(self, button, event): pw_dialog = ParentalPasswordDialog(self.win) if not pw_dialog.verify(): return level = self.parental_level.get_value() set_parental_level(level) set_setting('Parental-level', level) # track which parental control level people use track_data("parental-control-level-changed", { "level": level }) if level == 3.0: # If on the highest parental control, prompt user to relaunch # the browser kdialog = KanoDialog( title_text='Settings', description_text=("If any browsers are open, please relaunch " "them for this setting to take effect"), parent_window=self.win ) kdialog.run() else: # Only reboot for the lower parental controls common.need_reboot = True self.win.go_to_home()
def _show_icon_tutorial(self): try: from kano_profile.apps import save_app_state_variable, load_app_state_variable if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) except ImportError: # ignore problems importing kano_profile, as we don't want it to # be a dependency pass kdialog = KanoDialog( _("Add more apps to the desktop"), _( "Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'." ), { _("OK, GOT IT"): { "return_value": 0, "color": "green" } }, parent_window=self ) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def _show_icon_tutorial(self): try: from kano_profile.apps import save_app_state_variable, load_app_state_variable if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) except ImportError: # ignore problems importing kano_profile, as we don't want it to # be a dependency pass kdialog = KanoDialog( _("Add more apps to the desktop"), _("Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'."), {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def _show_username_taken_dialog(self, username): # TODO: refactor this track_data('world-registration-username-taken', {'username': username}) kd = KanoDialog(_("This username is taken!"), _("Try another one"), parent_window=self.win) kd.run() self.data_screen.username.set_text("") self.data_screen.validate_username() self._disable_register_button() self.data_screen.username.grab_focus()
def _show_username_taken_dialog(self, username): # TODO: refactor this track_data('world-registration-username-taken', {'username': username}) kd = KanoDialog( _("This username is taken!"), _("Try another one"), parent_window=self.win ) kd.run() self.data_screen.username.set_text("") self.data_screen.validate_username() self._disable_register_button() self.data_screen.username.grab_focus()
def get_sudo_password(heading, parent=None): entry = Gtk.Entry() entry.set_visibility(False) kdialog = KanoDialog( title_text=heading, description_text="Enter your system password - default is kano:", widget=entry, has_entry=True, global_style=True, parent_window=parent ) pw = kdialog.run() del kdialog del entry while not pam.authenticate(getpass.getuser(), pw): fail = KanoDialog( title_text=heading, description_text="The password was incorrect. Try again?", button_dict={ "YES": { "return_value": 0 }, "CANCEL": { "return_value": -1, "color": "red" } }, parent_window=parent ) rv = fail.run() del fail if rv < 0: return entry = Gtk.Entry() entry.set_visibility(False) kdialog = KanoDialog( title_text=heading, description_text="Re-enter your system password - default is kano:", widget=entry, has_entry=True, global_style=True, parent_window=parent ) pw = kdialog.run() del kdialog del entry return pw
def delete_user(self, *args): import pam password_input = Gtk.Entry() password_input.set_visibility(False) password_input.set_alignment(0.5) confirm = KanoDialog( title_text = _('Are you sure you want to delete this account?'), description_text = _('Enter {}\'s password - A reboot will be required'.format(self.user)), widget=password_input, has_entry=True, button_dict = [ { 'label': _('Cancel').upper(), 'color': 'red', 'return_value': False }, { 'label': _('Ok').upper(), 'color': 'green', 'return_value': True } ]) confirm.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) # Kano Dialog will return False if cancel button is clicked, or text from the entry field if Ok response=confirm.run() if response == False: return elif type(response) == str and not len(response): error = KanoDialog(title_text = _('Please enter the password for user {}'.format(self.user))) error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) error.run() return else: password=response # Authenticate user and schedule removal. Protect against unknown troubles. try: if pam.authenticate(self.user, password): info = KanoDialog(title_text = _('User {} scheduled for removal'.format(self.user)), \ description_text = _('Press OK to reboot')) info.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) info.run() os.system('sudo kano-init schedule delete-user "{}"'.format(self.user)) LightDM.restart() else: error = KanoDialog(title_text = _('Incorrect password for user {}'.format(self.user))) error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) error.run() except Exception as e: logger.error('Error deleting account {} - {}'.format(self.user, str(e))) error = KanoDialog(title_text = _('Could not delete account {}'.format(self.user))) error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) error.run()
def error(self, msg): error = KanoDialog( _('Error updating'), msg, { 'CLOSE': { 'return_value': True, 'color': 'red' } }, parent_window=self) error.run() # FIXME: This close doesn't work for some reason self.close_window()
def get_sudo_password(heading, parent=None): entry = Gtk.Entry() entry.set_visibility(False) kdialog = KanoDialog( title_text=heading, description_text=_("Enter your system password - default is kano:"), widget=entry, has_entry=True, global_style=True, parent_window=parent) pw = kdialog.run() del kdialog del entry while not pam.authenticate(getpass.getuser(), pw): fail = KanoDialog( title_text=heading, description_text=_("The password was incorrect. Try again?"), button_dict={ _("YES"): { "return_value": 0 }, _("CANCEL"): { "return_value": -1, "color": "red" } }, parent_window=parent) rv = fail.run() del fail if rv < 0: return entry = Gtk.Entry() entry.set_visibility(False) kdialog = KanoDialog( title_text=heading, description_text=_( "Re-enter your system password - default is kano:"), widget=entry, has_entry=True, global_style=True, parent_window=parent) pw = kdialog.run() del kdialog del entry return pw
def show_screenshot(self, widget, event): ''' Creates and displays a dialog with the screenshot image ''' height = Gdk.Screen().get_default().get_height() width = Gdk.Screen().get_default().get_width() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( SCREENSHOT_PATH, width * 0.5, height * 0.5) image = Gtk.Image.new_from_pixbuf(pixbuf) dialog = KanoDialog( _("Screenshot"), # noqa: F821 widget=image) dialog.run()
def verify(self): pw = self.run() if authenticate_parental_password(pw): return True fail = KanoDialog( title_text=_("Try again?"), description_text=_( "The password was incorrect. Changes not applied"), parent_window=self.win) fail.run() return False
def verify(self): pw = self.run() if authenticate_parental_password(pw): return True fail = KanoDialog( title_text='Try again?', description_text='The password was incorrect. Changes not applied', parent_window=self.win ) fail.run() return False
def show_terms_and_conditions(self, widget, event): '''This is the dialog containing the terms and conditions - same as shown before creating an account ''' legal_text = '' for file in os.listdir(legal_dir): with open(legal_dir + file, 'r') as f: legal_text = legal_text + f.read() + '\n\n\n' kdialog = KanoDialog(_("Terms and conditions"), "", scrolled_text=legal_text, parent_window=self.win) kdialog.run()
def show_terms_and_conditions(self, widget): """This is the dialog containing the terms and conditions - same as shown before creating an account """ window = widget.get_toplevel() # TODO: Figure out how/whether the legal text will be translated legal_text = "" for file in os.listdir(legal_dir): with open(legal_dir + file, "r") as f: legal_text = legal_text + f.read() + "\n\n\n" kdialog = KanoDialog(_("Terms and conditions"), "", scrolled_text=legal_text, parent_window=window) kdialog.run()
def _no_updates(self): self.destroy() self._set_normal_cursor() kill_flappy_judoka() no_updates = KanoDialog( _("No updates available"), _("Your system is already up to date"), {_("OK"): { 'return_value': True, 'color': 'green' }}) no_updates.run() self.close_window()
def error(self, msg): kill_flappy_judoka() error = KanoDialog( _("Error updating"), msg, {_("CLOSE"): { 'return_value': True, 'color': 'red' }}, parent_window=self) error.run() # FIXME: This close doesn't work for some reason self.close_window() return False
def error(self, msg): error = KanoDialog( _('Error updating'), msg, { 'CLOSE': { 'return_value': True, 'color': 'red' } }, parent_window=self) error.run() # FIXME: This close doesn't work for some reason self.close_window() return False
def _auth_error_cb(self, text, message_type=None): logger.info('There was an error logging in: {}'.format(text)) win = self.get_toplevel() win.go_to_users() self.login_btn.stop_spinner() self.login_btn.set_sensitive(True) self.newuser_btn.set_sensitive(True) error = KanoDialog(title_text=_('Error Synchronizing account'), description_text=text, parent_window=self.get_toplevel()) error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) error.run()
def _auth_error_cb(self, text, message_type=None): logger.info('There was an error logging in: {}'.format(text)) self.greeter.cancel_authentication() self.login_btn.stop_spinner() self.password.set_text('') win = self.get_toplevel() error = KanoDialog(title_text=_('Error Logging In'), description_text=text, parent_window=win) error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) error.run() win.go_to_users()
def _show_more_cb(self, widget): kdialog = KanoDialog( self._app["title"], self._app['description'] if "description" in self._app else self._app['tagline'], {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self._window) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run() return True
def verify_kit_is_plugged(): """ On Computer Kit 2 Pro, verify that the battery is plugged in and not depleting. For now, we rely on the user to tell us. Returns: is_plugged - bool whether the kit is plugged in (and battery isn't low) or not. """ has_battery = False is_battery_low = False is_plugged = True try: from kano_peripherals.wrappers.detection import is_ck2_pro, is_ckt has_battery = is_ck2_pro(retry_count=0) or is_ckt(retry_count=0) except: # Kano Peripherals doesn't support this function pass if has_battery: from kano.gtk3.kano_dialog import KanoDialog # Run the first dialog asking the user a question. dialog = KanoDialog( title_text=_("Power Required"), description_text=_("Is your computer plugged in?"), button_dict={ _("Yes"): {'color': 'green', 'return_value': True}, _("No"): {'color': 'red', 'return_value': False} } ) is_plugged = dialog.run() try: from kano_peripherals.ck2_pro_hat.driver.high_level import get_ck2_pro_hat_interface ck2pro_iface = get_ck2_pro_hat_interface(retry_count=0) is_battery_low = (ck2pro_iface and ck2pro_iface.is_battery_low()) except: # Kano Peripherals doesn't support this function pass header = "" if is_battery_low: header = _("Low Battery") else: header = _("Power Required") # If the answer was negative, show another message. if not is_plugged or is_battery_low: KanoDialog( title_text=header, description_text=_( "Sorry! You cannot update unless your computer is plugged in.\n" "Plug it in and try again!" ), button_dict={ _("Continue"): {'color': 'green'} } ).run() return is_plugged and not is_battery_low
def _show_not_internet_dialog(self): # TODO: refactor this kd = KanoDialog( _("You don't have internet"), _("Do you want to connect to WiFi?"), [ { 'label': _("YES"), 'color': 'green', 'return_value': 0 }, { 'label': _("NO"), 'color': 'red', 'return_value': 1 } ], parent_window=self.win ) response = kd.run() # Close the dialog while Gtk.events_pending(): # TODO: why is this needed? Gtk.main_iteration() if response == 0: subprocess.Popen("sudo kano-wifi-gui", shell=True)
def error(self, msg): kill_flappy_judoka() error = KanoDialog( _("Error updating"), msg, { _("CLOSE"): { 'return_value': True, 'color': 'red' } }, parent_window=self) error.run() # FIXME: This close doesn't work for some reason self.close_window() return False
def show_screenshot(self, widget, event): ''' Creates and displays a dialog with the screenshot image ''' height = Gdk.Screen().get_default().get_height() width = Gdk.Screen().get_default().get_width() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(SCREENSHOT_PATH, width * 0.5, height * 0.5) image = Gtk.Image.new_from_pixbuf(pixbuf) dialog = KanoDialog( _("Screenshot"), # noqa: F821 widget=image ) dialog.run()
def _no_updates(self): self.destroy() self._set_normal_cursor() no_updates = KanoDialog( _('No updates available'), _('Your system is already up to date'), { 'OK': { 'return_value': True, 'color': 'green' } }) no_updates.run() self.close_window()
def close_window(self, button, event): if common.need_reboot: kdialog = KanoDialog( _("Reboot?"), _("Your Kano needs to reboot for changes to apply"), [ { 'label': _("LATER"), 'color': 'grey', 'return_value': False }, { 'label': _("REBOOT NOW"), 'color': 'orange', 'return_value': True } ], parent_window=self.get_toplevel() ) kdialog.set_action_background('grey') do_reboot_now = kdialog.run() if do_reboot_now: os.system("sudo systemctl reboot") self._trigger_tracking_event() Gtk.main_quit()
def reset_button_cb(self, widget, event): # If enter key is pressed or mouse button is clicked if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return: kdialog = KanoDialog( title_text=_("This will reset your wallpaper and toolbar."), description_text=_("Do you want to continue?"), button_dict=[ { 'label': _("YES"), 'color': 'green', 'return_value': 'yes' }, { 'label': _("NO"), 'color': 'red', 'return_value': 'no' } ], parent_window=self.win ) response = kdialog.run() if response == 'yes': self.reset_desktop() self.win.go_to_home()
def show_login_status_dialog(self, title, description, return_value): '''Show a dialog with the title, description and that returns the return_value. Since this is used at the end of the login process, we also reset the cursor and kano button spinner. ''' kdialog = KanoDialog(title, description, {_("OK"): { 'return_value': return_value }}, parent_window=self.win) response = kdialog.run() if response == 'SUCCESS': if self.first_boot: self.win.remove_main_widget() SwagScreen(self.win) else: sys.exit(0) # If the login didn't work, try again. self.win.get_window().set_cursor(None) self.kano_button.stop_spinner() self.kano_button.set_sensitive(True) if not force_login: self.username_entry.grab_focus()
def _new_user_reboot(self, event=None, button=None): ''' Schedules kano-init to create a new user from scratch on next reboot, then performs the actual reboot ''' confirm = KanoDialog( title_text=_('Are you sure you want to create a new account?'), description_text=_('A reboot will be required'), button_dict=[ { 'label': _('Cancel').upper(), 'color': 'red', 'return_value': False }, { 'label': _('Create').upper(), 'color': 'green', 'return_value': True } ]) confirm.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) if confirm.run(): os.system("sudo kano-init schedule add-user") LightDM.restart()
def disconnect_wifi(): from kano.network import KwifiCache, disconnect from kano.gtk3.kano_dialog import KanoDialog iface = get_wlan_device() disconnect(iface) wificache = KwifiCache() wificache.empty() kdialog = KanoDialog( # Text from the content team. _("Disconnect complete - you're now offline."), ) kdialog.run() return 0
def show_login_status_dialog(self, title, description, return_value): '''Show a dialog with the title, description and that returns the return_value. Since this is used at the end of the login process, we also reset the cursor and kano button spinner. ''' kdialog = KanoDialog(title, description, {_("OK"): {"return_value": return_value}}, parent_window=self.win) response = kdialog.run() if response == "SUCCESS": if self.first_boot: self.win.remove_main_widget() SwagScreen(self.win) else: sys.exit(0) # If the login didn't work, try again. self.win.get_window().set_cursor(None) self.kano_button.stop_spinner() self.kano_button.set_sensitive(True) if not force_login: self.username_entry.grab_focus()
def _update_cb(self, widget): confirmation = KanoDialog( title_text=_("Updating {}").format(self._app["title"]), description_text=_( "This application will be updated " "Do you wish to proceed?" ), button_dict={ _("YES"): { "return_value": 0 }, _("NO"): { "return_value": -1, "color": "red" } }, parent_window=self._window ) confirmation.title.description.set_max_width_chars(40) rv = confirmation.run() del confirmation if rv < 0: return self._install_app(report_install=False)
def _installed_check(self): if is_app_installed(self._app): head = "{} is already installed".format(self._app["title"]) desc = "Would you like to update it?" dialog = KanoDialog( head, desc, { "YES": { "return_value": 0 }, "NO": { "return_value": -1 } }, parent_window=self ) rv = dialog.run() del dialog if rv == 0: self.set_report_install(False) return rv == 0 return True
def collect_new_username(self): username_entry = Gtk.Entry() kdialog = KanoDialog( title_text=_("Oops, that username has already been taken!"), description_text=_("Try picking another one."), button_dict=[ { "label": _("OK").upper() }, { "label": ("Cancel").upper(), "return_value": "CANCEL", "color": "red" } ], widget=username_entry, has_entry=True, parent_window=self.win ) rv = kdialog.run() if rv == "CANCEL": # let dialog close, do nothing self.page_control.enable_buttons() self.data_screen.enable_all() self.win.get_window().set_cursor(None) else: # rv will be the entry contents self.win.data["username"] = rv # Store this in kano profile straight away cache_data("username", rv) self.register_handler()
def _launch_app(self, cmd, args): try: os.execvp(cmd, [cmd] + args) except: pass # The execvp should not return, so if we reach this point, # there was an error. message = KanoDialog(_("Error"), _("Unable to start the application."), {_("OK"): { "return_value": 0, "color": "red" }}, parent_window=self._window) message.run()
def _create_dialog(self, title, description): # TODO: refactor this kdialog = KanoDialog( title, description, parent_window=self.win ) rv = kdialog.run() return rv
def _show_more_cb(self, widget): kdialog = KanoDialog( self._app["title"], self._app['description'] if "description" in self._app else self._app['tagline'], { _("OK, GOT IT"): { "return_value": 0, "color": "green" } }, parent_window=self._window ) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run() return True
def create_dialog(self, title, description): kdialog = KanoDialog( title, description, parent_window=self.win ) rv = kdialog.run() return rv
def show_terms_and_conditions(self, widget): """ This is the dialog containing the terms and conditions - same as shown before creating an account """ window = widget.get_toplevel() # TODO: Figure out how/whether the legal text will be translated legal_text = '' for file in os.listdir(legal_dir): with open(legal_dir + file, 'r') as f: legal_text = legal_text + f.read() + '\n\n\n' kdialog = KanoDialog(_("Terms and conditions"), "", scrolled_text=legal_text, parent_window=window) kdialog.run()
def _is_install_running(self): if self._install_thread.is_alive(): return True self.destroy() self._set_normal_cursor() kill_flappy_judoka() unexpected_quit = KanoDialog( _("The install quit unexpectedly"), _("Please try again later"), {_("OK"): { 'return_value': True, 'color': 'red' }}) unexpected_quit.run() self.close_window() return False
def _show_icon_tutorial(self): if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) kdialog = KanoDialog( _("Add more apps to the desktop"), _("Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'."), {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def _install(self): success = True if not self._icon_only: success = install_app(self._app, self._pw) if success: # write out the tmp json with open(self._tmp_data_file, "w") as f: f.write(json.dumps(self._app)) self._loc = install_link_and_icon(self._app['slug'], self._tmp_data_file, self._tmp_icon_file, self._pw) if not self._icon_only and self._add_to_desktop: add_to_desktop(self._app) head = _("Done!") message = _("{} installed successfully! " "Look for it in the Apps launcher.").format( self._app["title"]) else: head = _("Installation failed") message = _("{} cannot be installed at " "the moment. Please make sure your kit is connected " "to the internet and there is enough space left on " "your card.").format(self._app["title"]) dialog = KanoDialog( head, message, { _("OK"): { "return_value": 0 }, }, ) dialog.run() del dialog return success