Exemplo n.º 1
0
class Template(Gtk.Box):
    def __init__(self,
                 title,
                 description,
                 button_text,
                 is_plug=False,
                 back_btn=False):

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.title = Heading(title, description, is_plug, back_btn)
        self.title.container.set_margin_bottom(0)
        self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.align = Gtk.Alignment(xscale=0, yscale=0, xalign=0.5, yalign=0.3)
        self.align.add(self.box)
        self.kano_button = KanoButton(button_text)
        self.kano_button.pack_and_align()
        self.kano_button.align.set_padding(0, 30, 0, 0)

        self.pack_start(self.title.container, False, False, 0)
        self.pack_start(self.align, True, True, 0)
        self.pack_end(self.kano_button.align, False, False, 0)

    def set_prev_callback(self, cb):
        self.title.set_prev_callback(cb)
Exemplo n.º 2
0
class Template(Gtk.Box):

    def __init__(
        self,
        title,
        description,
        button_text,
        is_plug=False,
        back_btn=False
    ):

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.title = Heading(title, description, is_plug, back_btn)
        self.title.container.set_margin_bottom(0)
        self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.align = Gtk.Alignment(xscale=0, yscale=0, xalign=0.5, yalign=0.3)
        self.align.add(self.box)
        self.kano_button = KanoButton(button_text)
        self.kano_button.pack_and_align()
        self.kano_button.align.set_padding(0, 30, 0, 0)

        self.pack_start(self.title.container, False, False, 0)
        self.pack_start(self.align, True, True, 0)
        self.pack_end(self.kano_button.align, False, False, 0)

    def set_prev_callback(self, cb):
        self.title.set_prev_callback(cb)
Exemplo n.º 3
0
class AudioTemplate(Gtk.Box):
    """
    Template for audio screens
    """

    def __init__(self, img_path, title, description):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        if img_path:
            self.image = Gtk.Image.new_from_file(img_path)
            self.pack_start(self.image, False, False, 0)
        self.heading = Heading(title, description)

        icon_path = os.path.join(MEDIA_DIR, "play-sound.png")
        self.kano_button = KanoButton(text="PLAY SOUND", color="blue",
                                      icon_filename=icon_path)
        self.kano_button.pack_and_align()
        self.kano_button.set_margin_top(10)
        self.pack_start(self.heading.container, False, False, 0)
        self.pack_start(self.kano_button.align, False, False, 0)

        button_box = Gtk.ButtonBox(spacing=15)
        button_box.set_layout(Gtk.ButtonBoxStyle.CENTER)

        self.yes_button = KanoButton("YES")
        self.yes_button.set_sensitive(False)
        self.no_button = KanoButton("NO", color="red")
        self.no_button.set_sensitive(False)
        button_box.pack_start(self.yes_button, False, False, 0)
        button_box.pack_start(self.no_button, False, False, 0)
        button_box.set_margin_bottom(5)

        self.pack_start(button_box, False, False, 15)
Exemplo n.º 4
0
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win

        reset_button = KanoButton(text='RESET YOUR DESKTOP', color='orange')
        reset_button.connect('button-release-event', self.reset_button_cb)
        reset_button.connect('key-release-event', self.reset_button_cb)
        reset_button.pack_and_align()
        reset_button.align.set(0.5, 0.5, 0, 0)

        self.pack_start(reset_button.align, True, True, 0)
Exemplo n.º 5
0
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.get_style_context().add_class('notebook_page')

        reset_button = KanoButton(text=_("RESET YOUR DESKTOP"), color='orange')
        reset_button.connect('button-release-event', self.reset_button_cb)
        reset_button.connect('key-release-event', self.reset_button_cb)
        reset_button.pack_and_align()
        reset_button.align.set(0.5, 0.5, 0, 0)

        self.pack_start(reset_button.align, True, True, 0)
Exemplo n.º 6
0
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.get_style_context().add_class('notebook_page')

        reset_button = KanoButton(text=_("RESET YOUR DESKTOP"), color='orange')
        reset_button.connect('button-release-event', self.reset_button_cb)
        reset_button.connect('key-release-event', self.reset_button_cb)
        reset_button.pack_and_align()
        reset_button.align.set(0.5, 0.5, 0, 0)

        self.pack_start(reset_button.align, True, True, 0)
class NoInternet(Gtk.Box):
    selected_button = 0
    initial_button = 0

    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)
        # Main image
        image = Gtk.Image.new_from_file(media + "/Graphics/no-internet-screen.png")
        # Orange button
        later_button = OrangeButton(_("Later"))
        later_button.connect('button-release-event', self.win.close_window)
        # Green button
        self.kano_button = KanoButton(_("CONNECT NOW"))
        self.kano_button.pack_and_align()
        self.kano_button.connect('button-release-event', self.go_to_wifi)
        self.kano_button.connect('key-release-event', self.go_to_wifi)
        # Text label
        text_align = self.create_text_align()
        # Place elements
        image.set_margin_top(50)
        image.set_margin_bottom(30)
        self.pack_start(image, False, False, 0)
        self.pack_start(text_align, False, False, 2)
        self.pack_start(self.kano_button.align, False, False, 10)
        self.pack_start(later_button, False, False, 3)
        # Refresh window
        self.win.show_all()

    def go_to_wifi(self, widget=None, event=None):
        self.win.clear_win()
        SetWifi(self.win)

    def create_text_align(self):
        label = Gtk.Label(_("You need internet to continue"))
        label.get_style_context().add_class('about_version')

        align = Gtk.Alignment(xalign=0.5, xscale=0, yalign=0, yscale=0)
        align.add(label)

        return align
Exemplo n.º 8
0
class NoInternet(Gtk.Box):
    selected_button = 0
    initial_button = 0

    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)
        # Main image
        image = Gtk.Image.new_from_file(media + "/Graphics/no-internet-screen.png")
        # Orange button
        later_button = OrangeButton(_("Later"))
        later_button.connect('button-release-event', self.win.close_window)
        # Green button
        self.kano_button = KanoButton(_("CONNECT NOW"))
        self.kano_button.pack_and_align()
        self.kano_button.connect('button-release-event', self.go_to_wifi)
        self.kano_button.connect('key-release-event', self.go_to_wifi)
        # Text label
        text_align = self.create_text_align()
        # Place elements
        image.set_margin_top(50)
        image.set_margin_bottom(30)
        self.pack_start(image, False, False, 0)
        self.pack_start(text_align, False, False, 2)
        self.pack_start(self.kano_button.align, False, False, 10)
        self.pack_start(later_button, False, False, 3)
        # Refresh window
        self.win.show_all()

    def go_to_wifi(self, widget=None, event=None):
        self.win.clear_win()
        SetWifi(self.win)

    def create_text_align(self):
        label = Gtk.Label(_("You need internet to continue"))
        label.get_style_context().add_class('about_version')

        align = Gtk.Alignment(xalign=0.5, xscale=0, yalign=0, yscale=0)
        align.add(label)

        return align
Exemplo n.º 9
0
    def __init__(self, cb):
        super(CharacterWindow, self).__init__()
        self.get_style_context().add_class("character_window")
        self.set_decorated(False)
        self.close_cb = cb

        self.char_edit = CharacterCreator(randomise=True, no_sync=True)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        vbox.pack_start(self.char_edit, False, False, 0)
        button = KanoButton(_("OK"))
        button.connect("clicked", self.close_window)
        button.pack_and_align()

        self.connect("delete-event", Gtk.main_quit)
        self.set_keep_above(True)

        vbox.pack_start(button.align, False, False, 10)
        self.show_all()
Exemplo n.º 10
0
class LoggedIn(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title='Profile')
        self.set_size_request(200, 150)
        self.set_decorated(False)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_resizable(False)
        self.ok_button = KanoButton(_("OK"))
        self.ok_button.pack_and_align()
        self.ok_button.set_padding(20, 20, 0, 0)
        self.ok_button.connect('clicked', Gtk.main_quit)
        self.title = Heading(_("Logged in!"), _("You're already logged in"))
        self.main_container = Gtk.Box(
            orientation=Gtk.Orientation.VERTICAL, spacing=0)
        self.add(self.main_container)
        self.main_container.pack_start(self.title.container, False, False, 0)
        self.main_container.pack_start(self.ok_button.align, False, False, 0)

        # To get a logout button, uncomment out the lines below
        #self.logout_button = OrangeButton(_("Log out?"))
        #self.logout_button.connect('clicked', self.logout)
        #self.main_container.pack_start(self.logout_button, False, False, 0)

        self.connect('delete-event', Gtk.main_quit)
        self.show_all()

    def logged_out_screen(self):
        for child in self.main_container:
            self.main_container.remove(child)
        self.title.set_text(_("Logged out!"), "")
        self.main_container.pack_start(self.title.container, False, False, 0)
        self.main_container.pack_start(self.alignment, False, False, 0)

    def logout(self, event):
        remove_token()
        self.logged_out_screen()

    def close_window(self, event, button, win):
        self.ok_button.disconnect_handlers()
        cursor.arrow_cursor(None, None, win)
        Gtk.main_quit()
Exemplo n.º 11
0
class LoggedIn(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title='Profile')
        self.set_size_request(200, 150)
        self.set_decorated(False)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_resizable(False)
        self.ok_button = KanoButton(_("OK"))
        self.ok_button.pack_and_align()
        self.ok_button.set_padding(20, 20, 0, 0)
        self.ok_button.connect("clicked", Gtk.main_quit)
        self.title = Heading(_("Logged in!"), _("You're already logged in"))
        self.main_container = Gtk.Box(
            orientation=Gtk.Orientation.VERTICAL, spacing=0)
        self.add(self.main_container)
        self.main_container.pack_start(self.title.container, False, False, 0)
        self.main_container.pack_start(self.ok_button.align, False, False, 0)

        # To get a logout button, uncomment out the lines below
        #self.logout_button = OrangeButton(_("Log out?"))
        #self.logout_button.connect("clicked", self.logout)
        #self.main_container.pack_start(self.logout_button, False, False, 0)

        self.connect('delete-event', Gtk.main_quit)
        self.show_all()

    def logged_out_screen(self):
        for child in self.main_container:
            self.main_container.remove(child)
        self.title.set_text(_("Logged out!"), "")
        self.main_container.pack_start(self.title.container, False, False, 0)
        self.main_container.pack_start(self.alignment, False, False, 0)

    def logout(self, event):
        remove_token()
        self.logged_out_screen()

    def close_window(self, event, button, win):
        self.ok_button.disconnect_handlers()
        cursor.arrow_cursor(None, None, win)
        Gtk.main_quit()
Exemplo n.º 12
0
class ScrolledWindowTemplate(Gtk.Box):

    def __init__(
        self,
        title,
        description,
        button_text,
        orange_button_text=None
    ):

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.sw = ScrolledWindow()
        self.sw.apply_styling_to_widget(wide=False)

        self.title = Heading(title, description)
        self.kano_button = KanoButton(button_text)
        self.kano_button.pack_and_align()

        self.pack_start(self.title.container, False, False, 0)
        self.pack_start(self.sw, True, True, 0)

        if orange_button_text:
            box_align = Gtk.Alignment(xscale=0, xalign=0.5)
            button_box = Gtk.ButtonBox(
                orientation=Gtk.Orientation.HORIZONTAL, spacing=40
            )

            label = Gtk.Label("")
            self.orange_button = OrangeButton(orange_button_text)
            button_box.pack_start(label, False, False, 0)
            button_box.pack_start(self.kano_button.align, False, False, 0)
            button_box.pack_start(self.orange_button, False, False, 0)

            box_align.add(button_box)
            self.pack_start(box_align, False, False, 0)
        else:
            self.pack_start(self.kano_button.align, False, False, 0)

    def get_scrolled_window(self):
        return self.sw
Exemplo n.º 13
0
class AudioHintTemplate(TopImageTemplate):
    """
    Template for hints for audio setup
    """

    def __init__(self, img_path, title, description, kano_button_text,
                 hint_text=""):
        TopImageTemplate.__init__(self, img_path)

        self.heading = HintHeading(title, description, hint_text)
        self.pack_start(self.heading.container, False, False, 0)

        self.heading.description.set_margin_bottom(0)
        self.heading.container.set_margin_bottom(0)
        self.heading.container.set_size_request(590, -1)
        self.heading.container.set_spacing(0)

        self.kano_button = KanoButton(kano_button_text)
        self.kano_button.set_margin_top(30)
        self.kano_button.set_margin_bottom(30)
        self.kano_button.pack_and_align()

        self.pack_start(self.kano_button.align, False, False, 0)
Exemplo n.º 14
0
    def __init__(self, cb):
        super(CharacterWindow, self).__init__()
        self.get_style_context().add_class("character_window")
        self.set_decorated(False)
        self.close_cb = cb

        self.char_edit = CharacterCreator(randomise=True)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        vbox.pack_start(self.char_edit, False, False, 0)
        button = KanoButton("OK")
        button.connect("clicked", self.close_window)
        button.pack_and_align()

        self.connect("delete-event", Gtk.main_quit)
        self.set_keep_above(True)

        vbox.pack_start(button.align, False, False, 10)
        self.show_all()

        self.char_edit.show_pop_up_menu_for_category("judoka-faces")
        self.char_edit.select_category_button("judoka-faces")
Exemplo n.º 15
0
class CharacterWindow(Gtk.Window):
    def __init__(self, cb, css_path):
        super(CharacterWindow, self).__init__()

        apply_styling_to_screen(css_path)
        self.get_style_context().add_class("character_window")
        self.set_decorated(False)
        self.close_cb = cb

        self.char_edit = CharacterCreator(randomise=True, no_sync=True)
        self.char_edit.connect("character_changed",
                               self._make_button_sensitive)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        vbox.pack_start(self.char_edit, False, False, 0)
        self._kano_button = KanoButton("OK")
        self._kano_button.connect("clicked", self.close_window)
        self._kano_button.pack_and_align()
        self._kano_button.set_sensitive(False)

        self.connect("delete-event", Gtk.main_quit)
        self.set_keep_above(True)

        vbox.pack_start(self._kano_button.align, False, False, 10)
        self.show_all()

        self.char_edit.show_pop_up_menu_for_category("judoka-faces")
        self.char_edit.select_category_button("judoka-faces")

    def _make_button_sensitive(self, widget=None):
        self._kano_button.set_sensitive(True)

    def close_window(self, widget):
        self.char_edit.save()
        self.destroy()
        GLib.idle_add(self.close_cb)
Exemplo n.º 16
0
class ScrolledWindowTemplate(Gtk.Box):
    def __init__(self,
                 title,
                 description,
                 button_text,
                 orange_button_text=None):

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.sw = ScrolledWindow()
        self.sw.apply_styling_to_widget(wide=False)

        self.title = Heading(title, description)
        self.kano_button = KanoButton(button_text)
        self.kano_button.pack_and_align()

        self.pack_start(self.title.container, False, False, 0)
        self.pack_start(self.sw, True, True, 0)

        if orange_button_text:
            box_align = Gtk.Alignment(xscale=0, xalign=0.5)
            button_box = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL,
                                       spacing=40)

            label = Gtk.Label("")
            self.orange_button = OrangeButton(orange_button_text)
            button_box.pack_start(label, False, False, 0)
            button_box.pack_start(self.kano_button.align, False, False, 0)
            button_box.pack_start(self.orange_button, False, False, 0)

            box_align.add(button_box)
            self.pack_start(box_align, False, False, 0)
        else:
            self.pack_start(self.kano_button.align, False, False, 0)

    def get_scrolled_window(self):
        return self.sw
Exemplo n.º 17
0
class PasswordScreen(Gtk.Box):
    def __init__(self,
                 win,
                 wiface,
                 network_name,
                 encryption,
                 wrong_password=False):
        '''
        Show the screen with the option of adding a password
        and connecting to a network
        '''

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self._win = win
        self._win.set_main_widget(self)
        self._win.top_bar.enable_prev()
        self._wiface = wiface
        self._network_name = network_name
        self._encryption = encryption

        # Keep track if the user has already entered the wrong password before
        # so that we only pack the "password incorrect" label once
        self._wrong_password_used_before = False

        self._heading = Heading(_("Connect to the network"),
                                self._network_name, self._win.is_plug(), True)

        self._heading.set_prev_callback(self._refresh_networks)
        self._heading.container.set_margin_right(20)
        self._heading.container.set_margin_left(20)

        if wrong_password:
            image_path = os.path.join(img_dir, "password-fail.png")
            wrong_password = self._create_wrong_password_label()
            self._heading.container.pack_start(wrong_password, True, True, 0)
        else:
            image_path = os.path.join(img_dir, "password.png")

        self._padlock_image = Gtk.Image.new_from_file(image_path)

        self._password_entry = Gtk.Entry()
        self._password_entry.set_placeholder_text(_("Password"))
        self._password_entry.set_visibility(False)
        self._password_entry.get_style_context().add_class('password_entry')
        self._password_entry.set_margin_left(60)
        self._password_entry.set_margin_right(60)
        self._password_entry.connect('key-release-event',
                                     self._set_button_sensitive)
        # If Enter key is pressed on the password entry, we want to act as
        # though the connect_btn was clicked
        self._password_entry.connect('key-release-event',
                                     self._on_connect_key_wrapper)

        self._connect_btn = KanoButton(_("CONNECT"))
        self._connect_btn.connect('clicked', self._on_connect)
        self._connect_btn.set_sensitive(False)
        self._connect_btn.set_margin_right(100)
        self._connect_btn.set_margin_left(100)
        self._connect_btn.pack_and_align()

        self._show_password = Gtk.CheckButton.new_with_label(
            _("Show password"))
        self._show_password.get_style_context().add_class('show_password')
        self._show_password.connect('toggled',
                                    self._change_password_entry_visiblity)
        self._show_password.set_active(True)
        self._show_password.set_margin_left(100)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        vbox.pack_start(self._heading.container, False, False, 10)
        vbox.pack_start(self._padlock_image, False, False, 10)
        vbox.pack_start(self._password_entry, False, False, 10)
        vbox.pack_start(self._show_password, False, False, 10)
        vbox.pack_end(self._connect_btn.align, False, False, 40)

        # Entry should have the keyboard focus
        self._password_entry.grab_focus()

        self.show_all()

    def _create_wrong_password_label(self):
        label = Gtk.Label(_("Password incorrect"))
        label.get_style_context().add_class('wrong_password_label')
        return label

    def _change_password_entry_visiblity(self, widget):
        '''
        Depending on the checkbox, change the writing in the
        password entry to be readable.
        '''
        visibility = self._show_password.get_active()
        self._password_entry.set_visibility(visibility)

    def _refresh_networks(self, widget=None):
        from kano_wifi_gui.RefreshNetworks import RefreshNetworks
        RefreshNetworks(self._win)

    def _on_connect_key_wrapper(self, widget, event):
        if event.keyval == Gdk.KEY_Return:
            self._on_connect()

    def _on_connect(self, widget=None):
        passphrase = self._password_entry.get_text()
        ConnectToNetwork(self._win, self._network_name, passphrase,
                         self._encryption)

    def _set_button_sensitive(self, widget, event):
        '''
        Enable the Connect button only if the passphrase is non empty
        '''
        self._connect_btn.set_sensitive(widget.get_text_length() > 0)

    def _thread_finish(self, success):

        if success:
            self._success_screen()
        else:
            self._wrong_password_screen()

    def _success_screen(self):
        self._win.remove_main_widget()

        title = _("Success!")
        description = _("You're connected")
        buttons = [{
            'label': _("OK"),
            'color': 'green',
            'type': 'KanoButton',
            'callback': Gtk.main_quit
        }]
        img_path = os.path.join(img_dir, "internet.png")

        # Track that user connected online
        track_action('internet-connection-established')

        self._win.set_main_widget(
            Template(title, description, buttons, self._win.is_plug(),
                     img_path))

    def _disable_widgets_start_spinner(self):
        self._connect_btn.start_spinner()
        self._connect_btn.set_sensitive(False)
        self._win.top_bar.prev_button.set_sensitive(False)
        self._password_entry.set_sensitive(False)
        self._show_password.set_sensitive(False)

    def _enable_widgets_stop_spinner(self):
        self._connect_btn.stop_spinner()
        self._connect_btn.set_sensitive(True)
        self._win.top_bar.prev_button.set_sensitive(True)
        self._password_entry.set_sensitive(True)
        self._show_password.set_sensitive(True)
Exemplo n.º 18
0
class SetAbout(Gtk.Box):
    selected_button = 0
    initial_button = 0

    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)
        self.win.top_bar.enable_prev()
        self.win.change_prev_callback(self.win.go_to_home)

        image = Gtk.Image.new_from_file(media + "/Graphics/about-screen.png")

        version_align = self.create_align(
            "Kano OS v.{version}".format(version=get_current_version()),
            'about_version'
        )
        space_align = self.create_align(
            _("Disk space used: {used}B / {total}B").format(**get_space_available())
        )
        try:
            celsius = u"{:.1f}\N{DEGREE SIGN}C".format(get_temperature())
        except ValueError:
            celsius = "?"
        temperature_align = self.create_align(
            _(u"Temperature: {celsius}").format(celsius=celsius)
        )
        model_align = self.create_align(
            _("Model: {model}").format(model=get_model_name())
        )

        terms_and_conditions = OrangeButton(_("Terms and conditions"))
        terms_and_conditions.connect(
            'button_release_event', self.show_terms_and_conditions
        )

        credits_button = OrangeButton(_("Meet the team"))
        credits_button.connect(
            'button_release_event', self.show_credits
        )

        changelog_button = OrangeButton(_("Changelog"))
        changelog_button.connect(
            'button_release_event', self.show_changelog
        )

        self.kano_button = KanoButton(_("BACK"))
        self.kano_button.pack_and_align()

        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        hbox.pack_start(terms_and_conditions, False, False, 4)
        hbox.pack_start(credits_button, False, False, 4)
        hbox.pack_start(changelog_button, False, False, 4)
        hbutton_container = Gtk.Alignment(
            xalign=0.5, xscale=0, yalign=0, yscale=0
        )
        hbutton_container.add(hbox)

        image.set_margin_top(10)
        self.pack_start(image, False, False, 10)
        self.pack_start(version_align, False, False, 2)
        self.pack_start(space_align, False, False, 1)
        self.pack_start(temperature_align, False, False, 1)
        self.pack_start(model_align, False, False, 1)
        self.pack_start(hbutton_container, False, False, 3)
        self.pack_start(self.kano_button.align, False, False, 10)

        self.kano_button.connect('button-release-event', self.win.go_to_home)
        self.kano_button.connect('key-release-event', self.win.go_to_home)

        # Refresh window
        self.win.show_all()

    def create_align(self, text, css_class='about_label'):
        '''This styles the status information in the 'about' dialog
        '''

        label = Gtk.Label(text)
        label.get_style_context().add_class(css_class)

        align = Gtk.Alignment(xalign=0.5, xscale=0, yalign=0, yscale=0)
        align.add(label)

        return align

    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_credits(self, widget, event):
        '''Launch the credits
        '''

        os.system(
            "/usr/bin/kano-launcher \"kdesk-blur 'urxvt -bg "
            "rgba:0000/0000/0000/FFFF -title 'Credits' -e "
            "/usr/bin/kano-credits'\""
        )

    def show_changelog(self, widget, event):
        '''Launch chromium with the link of the relevent changelog
        '''

        # Assuming current_version is of the form 1.3.4
        current_version = get_current_version()

        # Full link should be analogous to
        # http://world.kano.me/forum/topic/kanux-beta-v1.2.3
        link = "http://world.kano.me/forum/topic/kanux-beta-v{}".format(
            current_version
        )

        launch_browser(link)
        return
Exemplo n.º 19
0
class RecoverUsername(Gtk.Box):
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_decorated(False)
        self.win.set_main_widget(self)

        self.heading = Heading(_("Forgotten your username"),
                               _("We'll send a reminder to your email"))
        self.pack_start(self.heading.container, False, False, 10)

        self.labelled_entries = LabelledEntries([{
            'heading': _("Email"),
            'subheading': ""
        }])
        align = Gtk.Alignment(xscale=0, xalign=0.5)
        self.pack_start(align, False, False, 15)

        self.labelled_entries.set(0, 0, 1, 1)
        self.labelled_entries.set_hexpand(True)

        align.add(self.labelled_entries)

        self.email_entry = self.labelled_entries.get_entry(0)
        self.email_entry.set_text("")
        self.email_entry.connect('key-release-event', self.activate)

        self.button = KanoButton(_("REQUEST REMINDER"))
        self.button.pack_and_align()
        self.button.connect('button-release-event', self.activate)
        self.button.connect('key-release-event', self.activate)
        self.button.set_padding(30, 30, 0, 0)

        self.pack_start(self.button.align, False, False, 0)
        self.email_entry.grab_focus()
        self.win.show_all()

    def activate(self, widget, event):
        if not hasattr(event, 'keyval') or event.keyval == 65293:
            watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
            self.win.get_window().set_cursor(watch_cursor)
            self.button.set_sensitive(False)
            self.button.start_spinner()

            thread = threading.Thread(target=self.send_new_password)
            thread.start()

    def send_new_password(self):
        # User may change email
        email = self.labelled_entries.get_entry(0).get_text()
        success, text = recover_username(email)
        if success:
            title = _("Success!")
            description = _("Sent a reminder to your email")
            button_dict = {
                _("GO TO LOGIN SCREEN"): {
                    'return_value': 12
                },
                _("QUIT"): {
                    'return_value': 10,
                    'color': 'red'
                }
            }
        else:
            title = _("Something went wrong!")
            description = text
            button_dict = {
                _("QUIT"): {
                    'return_value': 10,
                    'color': 'red'
                },
                _("TRY AGAIN"): {
                    'return_value': 11
                }
            }

        GObject.idle_add(self.finished_thread_cb, title, description,
                         button_dict)

    def finished_thread_cb(self, title, description, button_dict):
        kdialog = KanoDialog(title,
                             description,
                             button_dict=button_dict,
                             parent_window=self.win)
        response = kdialog.run()

        self.win.get_window().set_cursor(None)
        self.button.stop_spinner()
        self.button.set_sensitive(True)

        if response == 10:
            Gtk.main_quit()
        # stay put
        elif response == 11:
            pass
        elif response == 12:
            self.go_to_login_screen()

    def go_to_login_screen(self):
        self.win.remove_main_widget()
        Login(self.win)
Exemplo n.º 20
0
class FeedbackWindow(MainWindow):
    CLOSE_FEEDBACK = 0
    KEEP_OPEN = 1
    LAUNCH_WIFI = 2
    WIDTH = 400

    def __init__(self, bug_report=False):
        '''
        Initialises the window, creating a report or contact window
        '''
        MainWindow.__init__(self, subject='Kano Desktop Feedback Widget')
        self.kano_world_client = KanoWorld()
        self.bug_report = bug_report
        if self.bug_report:
            self.report_window()
        else:
            self.contact_window()

    def contact_window(self):
        '''
        Contact Us window
        Contains text view and a Send button
        '''
        # delete the directory containing all the info we'll send, and recreate
        delete_tmp_dir()
        create_tmp_dir()

        ApplicationWindow.__init__(
            self,
            _('Contact Us'),  # noqa: F821
            self.WIDTH,
            0.35)

        screen = Gdk.Screen.get_default()
        specific_provider = Gtk.CssProvider()
        specific_provider.load_from_path(Media.media_dir() + 'css/style.css')
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, specific_provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

        # Make sure this window has no icon in the task bar
        # so it plays nice with kdesk-blur
        self.set_property('skip-taskbar-hint', True)

        self._grid = Gtk.Grid()

        # Create top bar
        self._top_bar = TopBar(
            title=_("Contact Us"),  # noqa: F821
            window_width=self.WIDTH,
            has_buttons=False)
        self._top_bar.set_close_callback(Gtk.main_quit)
        self.set_decorated(True)
        self.set_titlebar(self._top_bar)

        # Create Text view
        self._text = Gtk.TextView()
        self._text.set_editable(True)
        self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        self._text.set_size_request(self.WIDTH, -1)
        self._text.set_sensitive(self._pii_allowed())

        self._textbuffer = self._text.get_buffer()
        if self._pii_allowed():
            self._textbuffer.set_text(
                _("Type your feedback here!"))  # noqa: F821
        else:
            self._textbuffer.set_text(
                _("Want to send us more information? Ask your parent to check their email."
                  ))  # noqa: F821
        self._clear_buffer_handler_id = self._textbuffer.connect(
            "insert-text", self.clear_buffer)

        scrolledwindow = ScrolledWindow()
        scrolledwindow.set_vexpand(True)
        scrolledwindow.set_policy(Gtk.PolicyType.NEVER,
                                  Gtk.PolicyType.AUTOMATIC)
        scrolledwindow.apply_styling_to_widget()
        scrolledwindow.add(self._text)
        scrolledwindow.set_margin_left(2)
        scrolledwindow.set_margin_right(2)
        scrolledwindow.set_margin_top(2)
        scrolledwindow.set_margin_bottom(2)

        # Very hacky way to get a border: create a grey event box
        # which is a little bigger than the widget below
        border = Gtk.EventBox()
        border.get_style_context().add_class("grey")
        border.add(scrolledwindow)
        self._grid.attach(border, 0, 0, 1, 1)
        border.set_margin_left(20)
        border.set_margin_right(20)
        border.set_margin_top(10)
        border.set_margin_bottom(20)

        # Create send button
        self._send_button = KanoButton(_("SEND")  # noqa: F821
                                       )
        self._send_button.set_sensitive(not self._pii_allowed())
        self._send_button.connect("button_press_event", self.send_feedback)
        self._send_button.pack_and_align()
        self._send_button.align.set_padding(10, 10, 0, 0)

        bottom_background = Gtk.EventBox()
        bottom_background.get_style_context().add_class("grey")
        bottom_background.add(self._send_button.align)

        self._grid.attach(bottom_background, 0, 1, 1, 1)

        self._grid.set_row_spacing(0)
        self.set_main_widget(self._grid)

        # kano-profile stat collection
        try:
            from kano_profile.badges import \
                increment_app_state_variable_with_dialog
            increment_app_state_variable_with_dialog('kano-feedback', 'starts',
                                                     1)
        except Exception:
            pass

    def report_window(self):
        '''
        Report window
        Contains 2 text views and Take Screenshot, Add Image and Send buttons
        '''
        ApplicationWindow.__init__(
            self,
            _('Report a Problem'),  # noqa: F821
            self.WIDTH,
            0.35)

        screen = Gdk.Screen.get_default()
        specific_provider = Gtk.CssProvider()
        specific_provider.load_from_path(Media.media_dir() + 'css/style.css')
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, specific_provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

        self.set_icon_name("feedback")
        self._grid = Gtk.Grid()

        # Create top bar
        self._top_bar = TopBar(
            title=_("Report a Problem"),  # noqa: F821
            window_width=self.WIDTH,
            has_buttons=False)
        self._top_bar.set_close_callback(Gtk.main_quit)
        self.set_decorated(True)
        self.set_titlebar(self._top_bar)

        self.entry = Gtk.Entry()
        if self._pii_allowed():
            self.entry.props.placeholder_text = _(
                "Add subject (optional)")  # noqa: F821
        else:
            self.entry.props.placeholder_text = _(
                "Want to send us more information?")  # noqa: F821
        self.entry.set_margin_left(20)
        self.entry.set_margin_right(20)
        self.entry.set_margin_top(20)
        self.entry.set_margin_bottom(10)
        self.entry.set_sensitive(self._pii_allowed())
        self._grid.attach(self.entry, 0, 0, 1, 1)

        # Create Text view
        self._text = Gtk.TextView()
        self._text.set_editable(True)
        self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        self._text.set_size_request(self.WIDTH, -1)
        self._text.set_sensitive(self._pii_allowed())

        self._textbuffer = self._text.get_buffer()
        if self._pii_allowed():
            self._textbuffer.set_text(
                _("Type your problem here!"))  # noqa: F821
        else:
            self._textbuffer.set_text(
                _("Ask your parent to check their email."))  # noqa: F821

        self._clear_buffer_handler_id = self._textbuffer.connect(
            "insert-text", self.clear_buffer)

        scrolledwindow = ScrolledWindow()
        scrolledwindow.set_vexpand(True)
        scrolledwindow.set_policy(Gtk.PolicyType.NEVER,
                                  Gtk.PolicyType.AUTOMATIC)
        scrolledwindow.apply_styling_to_widget()
        scrolledwindow.add(self._text)
        scrolledwindow.set_margin_left(2)
        scrolledwindow.set_margin_right(2)
        scrolledwindow.set_margin_top(2)
        scrolledwindow.set_margin_bottom(2)

        # Very hacky way to get a border: create a grey event box
        # which is a little bigger than the widget below
        border = Gtk.EventBox()
        border.get_style_context().add_class("grey")
        border.add(scrolledwindow)
        self._grid.attach(border, 0, 1, 1, 1)
        border.set_margin_left(20)
        border.set_margin_right(20)
        border.set_margin_top(10)
        border.set_margin_bottom(20)

        # Create take screenshot button
        self._screenshot_button = KanoButton(
            _("TAKE SCREENSHOT"),  # noqa: F821
            "blue")
        self._screenshot_button.set_sensitive(self._pii_allowed())
        self._screenshot_button.connect("button_press_event",
                                        self.screenshot_clicked)

        # Create attach screenshot button
        self._attach_button = KanoButton(
            _("ADD IMAGE"),  # noqa: F821
            "blue")
        self._attach_button.set_sensitive(self._pii_allowed())
        self._attach_button.connect("button_press_event", self.attach_clicked)

        # Create send button
        self._send_button = KanoButton(_("SEND")  # noqa: F821
                                       )
        self._send_button.set_sensitive(not self._pii_allowed())
        self._send_button.connect("button_press_event", self.send_feedback)
        self._send_button.pack_and_align()
        self._send_button.set_margin(10, 0, 10, 0)

        self.screenshot_box = Gtk.ButtonBox()
        self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER)
        self.screenshot_box.set_spacing(20)
        self.pack_screenshot_buttons()
        self.screenshot_box.set_margin_bottom(20)

        self._grid.attach(self.screenshot_box, 0, 2, 1, 1)

        # Create grey box to put the button in
        self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.bottom_box.pack_start(self._send_button.align, False, False, 0)

        bottom_background = Gtk.EventBox()
        bottom_background.get_style_context().add_class("grey")
        bottom_background.add(self.bottom_box)

        self._grid.attach(bottom_background, 0, 3, 1, 1)

        self._grid.set_row_spacing(0)
        self.set_main_widget(self._grid)

        # kano-profile stat collection
        try:
            from kano_profile.badges import increment_app_state_variable_with_dialog
            increment_app_state_variable_with_dialog('kano-feedback', 'starts',
                                                     1)
        except Exception:
            pass

    def screenshot_clicked(self, button=None, event=None):
        '''
        Takes a screenshot while minimising the window
        '''
        # minimise the window
        self.iconify()
        take_screenshot()
        self.include_screenshot()
        # restore the window
        self.deiconify()

    def attach_clicked(self, button=None, event=None):
        '''
        Opens the File Chooser Dialog.
        If image selected then copy it to the feedback folder
        '''
        screenshot = None
        # Open file manager
        dialog = Gtk.FileChooserDialog(
            _("Please choose a file"),  # noqa: F821
            self,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN,
             Gtk.ResponseType.OK))

        self.add_filters(dialog)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            screenshot = dialog.get_filename()

        dialog.destroy()
        # Copy image file into feedback folder
        if screenshot is not None:
            copy_screenshot(screenshot)
            self.include_screenshot()

    def add_filters(self, dialog):
        '''
        Add image type filters
        Used for the File Chooser Dialog
        '''
        # Image filter
        filter_images = Gtk.FileFilter()
        filter_images.set_name("Images")
        filter_images.add_mime_type("image/png")
        filter_images.add_mime_type("image/jpeg")
        filter_images.add_mime_type("image/gif")
        filter_images.add_pattern("*.png")
        filter_images.add_pattern("*.jpg")
        filter_images.add_pattern("*.gif")
        filter_images.add_pattern("*.tif")
        filter_images.add_pattern("*.xpm")
        dialog.add_filter(filter_images)

        # Any file filter
        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_pattern("*")
        dialog.add_filter(filter_any)

    def include_screenshot(self):
        '''
        This is the box containing the filename of the screenshot,
        and the option to display it or remove it
        '''
        if not hasattr(self, "screenshot"):

            # We pack the buttons into an event box with styling
            # so that we can have a container with a border radius
            # without having ugly gaps between the buttons.
            self.screenshot = Gtk.EventBox()
            self.screenshot.get_style_context().add_class("kano_button")
            self.screenshot.get_style_context().add_class("blue_background")

            remove_screenshot = Gtk.Button()
            attach_cursor_events(remove_screenshot)
            remove_icon = Gtk.Image.new_from_file(
                "/usr/share/kano-feedback/media/icons/close.png")
            remove_screenshot.add(remove_icon)
            remove_screenshot.connect("button-release-event",
                                      self.remove_screenshot)
            remove_screenshot.get_style_context().add_class("blue_background")

            show_screenshot = Gtk.Button()
            attach_cursor_events(show_screenshot)
            show_icon = Gtk.Image()
            show_icon.set_from_file(
                "/usr/share/kano-feedback/media/icons/preview.png")
            show_screenshot.add(show_icon)
            show_screenshot.connect("button-release-event",
                                    self.show_screenshot)
            show_screenshot.get_style_context().add_class("blue_background")

            label = Gtk.Label(SCREENSHOT_NAME.upper())
            label.set_padding(10, 0)
            box = Gtk.Box()
            box.pack_start(label, False, False, 0)
            box.pack_end(remove_screenshot, False, False, 0)
            box.pack_end(show_screenshot, False, False, 0)

            self.screenshot.add(box)

        self.screenshot_box.remove(self._screenshot_button)
        self.screenshot_box.remove(self._attach_button)
        self.screenshot_box.pack_start(self.screenshot, False, False, 0)

    def remove_screenshot(self, widget, event):
        '''
        Remove screenshot button action
        '''
        delete_screenshot()
        self.screenshot_box.remove(self.screenshot)
        self.pack_screenshot_buttons()
        self.show_all()

    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 pack_screenshot_buttons(self):
        '''
        Pack the screenshot buttons into a box
        '''
        self.screenshot_box.pack_start(self._screenshot_button, False, False,
                                       0)
        self.screenshot_box.set_child_non_homogeneous(self._screenshot_button,
                                                      True)
        self.screenshot_box.pack_start(self._attach_button, False, False, 0)
        self.screenshot_box.set_child_non_homogeneous(self._attach_button,
                                                      True)

    def _pii_allowed(self):
        """
        Helper to check whether or not users are allowed to send us text,
        screenshots, images.
        """
        return (self.kano_world_client.is_logged_in()
                and self.kano_world_client.get_account_verified())
Exemplo n.º 21
0
class FeedbackWindow(MainWindow):
    CLOSE_FEEDBACK = 0
    KEEP_OPEN = 1
    LAUNCH_WIFI = 2
    WIDTH = 400

    def __init__(self, bug_report=False):
        '''
        Initialises the window, creating a report or contact window
        '''
        MainWindow.__init__(self, subject='Kano Desktop Feedback Widget')
        self.bug_report = bug_report
        if self.bug_report:
            self.report_window()
        else:
            self.contact_window()

    def contact_window(self):
        '''
        Contact Us window
        Contains text view and a Send button
        '''
        # delete the directory containing all the info we'll send, and recreate
        delete_tmp_dir()
        create_tmp_dir()

        ApplicationWindow.__init__(
            self,
            _('Contact Us'),  # noqa: F821
            self.WIDTH,
            0.35
        )

        screen = Gdk.Screen.get_default()
        specific_provider = Gtk.CssProvider()
        specific_provider.load_from_path(Media.media_dir() + 'css/style.css')
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, specific_provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

        # Make sure this window has no icon in the task bar
        # so it plays nice with kdesk-blur
        self.set_property('skip-taskbar-hint', True)

        self._grid = Gtk.Grid()

        # Create top bar
        self._top_bar = TopBar(
            title=_("Contact Us"),  # noqa: F821
            window_width=self.WIDTH,
            has_buttons=False
        )
        self._top_bar.set_close_callback(Gtk.main_quit)
        self.set_decorated(True)
        self.set_titlebar(self._top_bar)

        # Create Text view
        self._text = Gtk.TextView()
        self._text.set_editable(True)
        self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        self._text.set_size_request(self.WIDTH, -1)

        self._textbuffer = self._text.get_buffer()
        self._textbuffer.set_text(
            _("Type your feedback here!")  # noqa: F821
        )
        self._clear_buffer_handler_id = self._textbuffer.connect(
            "insert-text", self.clear_buffer
        )

        scrolledwindow = ScrolledWindow()
        scrolledwindow.set_vexpand(True)
        scrolledwindow.set_policy(Gtk.PolicyType.NEVER,
                                  Gtk.PolicyType.AUTOMATIC)
        scrolledwindow.apply_styling_to_widget()
        scrolledwindow.add(self._text)
        scrolledwindow.set_margin_left(2)
        scrolledwindow.set_margin_right(2)
        scrolledwindow.set_margin_top(2)
        scrolledwindow.set_margin_bottom(2)

        # Very hacky way to get a border: create a grey event box
        # which is a little bigger than the widget below
        border = Gtk.EventBox()
        border.get_style_context().add_class("grey")
        border.add(scrolledwindow)
        self._grid.attach(border, 0, 0, 1, 1)
        border.set_margin_left(20)
        border.set_margin_right(20)
        border.set_margin_top(10)
        border.set_margin_bottom(20)

        # Create send button
        self._send_button = KanoButton(
            _("SEND")  # noqa: F821
        )
        self._send_button.set_sensitive(False)
        self._send_button.connect("button_press_event", self.send_feedback)
        self._send_button.pack_and_align()
        self._send_button.align.set_padding(10, 10, 0, 0)

        bottom_background = Gtk.EventBox()
        bottom_background.get_style_context().add_class("grey")
        bottom_background.add(self._send_button.align)

        self._grid.attach(bottom_background, 0, 1, 1, 1)

        self._grid.set_row_spacing(0)
        self.set_main_widget(self._grid)

        # kano-profile stat collection
        try:
            from kano_profile.badges import \
                increment_app_state_variable_with_dialog
            increment_app_state_variable_with_dialog(
                'kano-feedback', 'starts', 1
            )
        except Exception:
            pass

    def report_window(self):
        '''
        Report window
        Contains 2 text views and Take Screenshot, Add Image and Send buttons
        '''
        ApplicationWindow.__init__(
            self,
            _('Report a Problem'),  # noqa: F821
            self.WIDTH,
            0.35
        )

        screen = Gdk.Screen.get_default()
        specific_provider = Gtk.CssProvider()
        specific_provider.load_from_path(Media.media_dir() + 'css/style.css')
        style_context = Gtk.StyleContext()
        style_context.add_provider_for_screen(screen, specific_provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

        self.set_icon_name("feedback")
        self._grid = Gtk.Grid()

        # Create top bar
        self._top_bar = TopBar(
            title=_("Report a Problem"),  # noqa: F821
            window_width=self.WIDTH,
            has_buttons=False
        )
        self._top_bar.set_close_callback(Gtk.main_quit)
        self.set_decorated(True)
        self.set_titlebar(self._top_bar)

        self.entry = Gtk.Entry()
        self.entry.props.placeholder_text = \
            _("Add subject (optional)")  # noqa: F821
        self.entry.set_margin_left(20)
        self.entry.set_margin_right(20)
        self.entry.set_margin_top(20)
        self.entry.set_margin_bottom(10)
        self._grid.attach(self.entry, 0, 0, 1, 1)

        # Create Text view
        self._text = Gtk.TextView()
        self._text.set_editable(True)
        self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        self._text.set_size_request(self.WIDTH, -1)

        self._textbuffer = self._text.get_buffer()
        self._textbuffer.set_text(
            _("Type your problem here!")  # noqa: F821
        )

        self._clear_buffer_handler_id = self._textbuffer.connect(
            "insert-text", self.clear_buffer
        )

        scrolledwindow = ScrolledWindow()
        scrolledwindow.set_vexpand(True)
        scrolledwindow.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC
        )
        scrolledwindow.apply_styling_to_widget()
        scrolledwindow.add(self._text)
        scrolledwindow.set_margin_left(2)
        scrolledwindow.set_margin_right(2)
        scrolledwindow.set_margin_top(2)
        scrolledwindow.set_margin_bottom(2)

        # Very hacky way to get a border: create a grey event box
        # which is a little bigger than the widget below
        border = Gtk.EventBox()
        border.get_style_context().add_class("grey")
        border.add(scrolledwindow)
        self._grid.attach(border, 0, 1, 1, 1)
        border.set_margin_left(20)
        border.set_margin_right(20)
        border.set_margin_top(10)
        border.set_margin_bottom(20)

        # Create take screenshot button
        self._screenshot_button = KanoButton(
            _("TAKE SCREENSHOT"),  # noqa: F821
            "blue"
        )
        self._screenshot_button.set_sensitive(True)
        self._screenshot_button.connect("button_press_event",
                                        self.screenshot_clicked)

        # Create attach screenshot button
        self._attach_button = KanoButton(
            _("ADD IMAGE"),  # noqa: F821
            "blue"
        )
        self._attach_button.set_sensitive(True)
        self._attach_button.connect("button_press_event", self.attach_clicked)

        # Create send button
        self._send_button = KanoButton(
            _("SEND")  # noqa: F821
        )
        self._send_button.set_sensitive(False)
        self._send_button.connect("button_press_event", self.send_feedback)
        self._send_button.pack_and_align()
        self._send_button.set_margin(10, 0, 10, 0)

        self.screenshot_box = Gtk.ButtonBox()
        self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER)
        self.screenshot_box.set_spacing(20)
        self.pack_screenshot_buttons()
        self.screenshot_box.set_margin_bottom(20)

        self._grid.attach(self.screenshot_box, 0, 2, 1, 1)

        # Create grey box to put the button in
        self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.bottom_box.pack_start(self._send_button.align, False, False, 0)

        bottom_background = Gtk.EventBox()
        bottom_background.get_style_context().add_class("grey")
        bottom_background.add(self.bottom_box)

        self._grid.attach(bottom_background, 0, 3, 1, 1)

        self._grid.set_row_spacing(0)
        self.set_main_widget(self._grid)

        # kano-profile stat collection
        try:
            from kano_profile.badges import increment_app_state_variable_with_dialog
            increment_app_state_variable_with_dialog(
                'kano-feedback', 'starts', 1
            )
        except Exception:
            pass

    def screenshot_clicked(self, button=None, event=None):
        '''
        Takes a screenshot while minimising the window
        '''
        # minimise the window
        self.iconify()
        take_screenshot()
        self.include_screenshot()
        # restore the window
        self.deiconify()

    def attach_clicked(self, button=None, event=None):
        '''
        Opens the File Chooser Dialog.
        If image selected then copy it to the feedback folder
        '''
        screenshot = None
        # Open file manager
        dialog = Gtk.FileChooserDialog(
            _("Please choose a file"),  # noqa: F821
            self,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL,
            Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
        )

        self.add_filters(dialog)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            screenshot = dialog.get_filename()

        dialog.destroy()
        # Copy image file into feedback folder
        if screenshot is not None:
            copy_screenshot(screenshot)
            self.include_screenshot()

    def add_filters(self, dialog):
        '''
        Add image type filters
        Used for the File Chooser Dialog
        '''
        # Image filter
        filter_images = Gtk.FileFilter()
        filter_images.set_name("Images")
        filter_images.add_mime_type("image/png")
        filter_images.add_mime_type("image/jpeg")
        filter_images.add_mime_type("image/gif")
        filter_images.add_pattern("*.png")
        filter_images.add_pattern("*.jpg")
        filter_images.add_pattern("*.gif")
        filter_images.add_pattern("*.tif")
        filter_images.add_pattern("*.xpm")
        dialog.add_filter(filter_images)

        # Any file filter
        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_pattern("*")
        dialog.add_filter(filter_any)

    def include_screenshot(self):
        '''
        This is the box containing the filename of the screenshot,
        and the option to display it or remove it
        '''
        if not hasattr(self, "screenshot"):

            # We pack the buttons into an event box with styling
            # so that we can have a container with a border radius
            # without having ugly gaps between the buttons.
            self.screenshot = Gtk.EventBox()
            self.screenshot.get_style_context().add_class("kano_button")
            self.screenshot.get_style_context().add_class("blue_background")

            remove_screenshot = Gtk.Button()
            attach_cursor_events(remove_screenshot)
            remove_icon = Gtk.Image.new_from_file("/usr/share/kano-feedback/media/icons/close.png")
            remove_screenshot.add(remove_icon)
            remove_screenshot.connect("button-release-event",
                                      self.remove_screenshot)
            remove_screenshot.get_style_context().add_class("blue_background")

            show_screenshot = Gtk.Button()
            attach_cursor_events(show_screenshot)
            show_icon = Gtk.Image()
            show_icon.set_from_file("/usr/share/kano-feedback/media/icons/preview.png")
            show_screenshot.add(show_icon)
            show_screenshot.connect("button-release-event", self.show_screenshot)
            show_screenshot.get_style_context().add_class("blue_background")

            label = Gtk.Label(SCREENSHOT_NAME.upper())
            label.set_padding(10, 0)
            box = Gtk.Box()
            box.pack_start(label, False, False, 0)
            box.pack_end(remove_screenshot, False, False, 0)
            box.pack_end(show_screenshot, False, False, 0)

            self.screenshot.add(box)

        self.screenshot_box.remove(self._screenshot_button)
        self.screenshot_box.remove(self._attach_button)
        self.screenshot_box.pack_start(self.screenshot, False, False, 0)

    def remove_screenshot(self, widget, event):
        '''
        Remove screenshot button action
        '''
        delete_screenshot()
        self.screenshot_box.remove(self.screenshot)
        self.pack_screenshot_buttons()
        self.show_all()

    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 pack_screenshot_buttons(self):
        '''
        Pack the screenshot buttons into a box
        '''
        self.screenshot_box.pack_start(self._screenshot_button,
                                       False, False, 0)
        self.screenshot_box.set_child_non_homogeneous(self._screenshot_button,
                                                      True)
        self.screenshot_box.pack_start(self._attach_button, False, False, 0)
        self.screenshot_box.set_child_non_homogeneous(self._attach_button,
                                                      True)
Exemplo n.º 22
0
class NetworkScreen(Gtk.Box):

    def __init__(self, win, network_list):

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
        self._win = win
        self._wiface = self._win.wiface

        # The network that the user selects
        self._selected_network = {}

        # Setting new window here
        self._win.set_main_widget(self)
        self._win.top_bar.disable_prev()

        box = self._create_main_box(network_list)
        self.add(box)

        self._win.show_all()

    def _create_main_box(self, network_list):
        '''Show the screen with the different WiFi networks
        '''

        heading = Heading(
            _("Connect to WiFi"),
            _("Choose a network"),
            self._win.is_plug(),
            back_btn=False
        )

        # This box is to pack everything in the window
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # For now, pack the network into a scrolled window
        sw = ScrolledWindow()
        sw.apply_styling_to_widget()
        sw.set_size_request(-1, 215)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self._network_box = self._create_network_box(network_list)
        sw.add(self._network_box)

        # Pack the scrolled window into an event box to give the illusion of a
        # border
        sw_border = self._add_border_to_widget(sw)
        sw_border.set_margin_right(30)
        sw_border.set_margin_left(30)
        sw_border.set_margin_bottom(20)
        sw_border.set_margin_top(10)

        # Then pack all the elements into the vbox
        vbox.pack_start(heading.container, False, False, 0)
        vbox.pack_start(sw_border, False, False, 0)

        # Pack in the refresh connect buttons
        button_box = self._create_refresh_connect_buttons()
        vbox.pack_end(button_box, False, False, 30)

        return vbox

    def _create_network_box(self, network_list):
        '''Create the box containing the list of networks
        '''
        # Setting up the box in which the network elements are to be positioned
        network_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # Are these used anywhere?
        self._network_btns = []
        network_connection = is_connected(self._wiface)

        # The network connection
        network_name = network_connection[0]
        connected = network_connection[3]

        image_path = os.path.join(img_dir, "padlock.png")

        # If the network list is empty, display a message to show it's not
        # broken
        if not len(network_list):
            no_networks_label = Gtk.Label(_("No networks detected!"))
            no_networks_label.get_style_context().add_class('no_networks_label')
            no_networks_label.set_margin_top(80)
            network_box.pack_start(no_networks_label, False, False, 0)
            return network_box

        # Otherwise, pack the networks into the scrolled window
        for network in network_list:

            # Network selection must be able to receive events
            network_btn = Gtk.Button()

            # Needs a box packed into it for the label and possibly
            # an icon
            box = Gtk.Box()
            network_btn.add(box)
            network_btn.get_style_context().add_class('network_btn')
            attach_cursor_events(network_btn)

            # Box must contain label of the network name
            label = Gtk.Label(network['essid'])
            box.pack_start(label, False, False, 0)

            # If the network name of the button matches the last attempted
            # connection, and we're connected to the internet, then
            # put a tick next to the name.

            # TODO: Since connected shows if you're connected to internet
            # you can be connected to ethernet and thus be shown to be
            # connected to the wrong network.
            if network['essid'] == network_name and \
                    connected:
                tick = tick_icon()
                box.pack_start(tick, False, False, 0)

            network_btn.connect(
                'clicked', self._select_network, network, network_connection
            )

            # Add padlock to the items that require a password
            if network['encryption'] != 'off':
                padlock_image = Gtk.Image.new_from_file(image_path)
                box.pack_end(padlock_image, False, False, 0)

            # Pack into the GUI for the networks
            network_box.pack_start(network_btn, False, False, 0)
            self._network_btns.append(network_btn)

        return network_box

    def _add_border_to_widget(self, widget):
        '''Add a grey border to the widget that is entered as an argument.
        This is done by creating a grey event box and packing a white box with
        a margin in it.
        '''

        white_foreground = Gtk.EventBox()
        white_foreground.get_style_context().add_class('white')
        white_foreground.set_margin_left(3)
        white_foreground.set_margin_bottom(3)
        white_foreground.set_margin_top(3)
        white_foreground.set_margin_right(3)

        # Pack the scrolled window into an event box to give the illusion of a
        # border
        grey_border = Gtk.EventBox()
        grey_border.get_style_context().add_class('grey')
        grey_border.add(white_foreground)

        white_foreground.add(widget)

        return grey_border

    def _create_refresh_connect_buttons(self):
        '''Create the buttons used for the refresh button and the
        to connect to a network, and pack them into a button box.
        Returns the button box.
        '''

        self._connect_btn = KanoButton(_("CONNECT"))
        self._connect_btn.pack_and_align()
        self.connect_handler = self._connect_btn.connect(
            'clicked', self._first_time_connect
        )
        self._connect_btn.set_sensitive(False)
        self._refresh_btn = self._create_refresh_button()

        # For now, show both connect and refresh buttons
        buttonbox = Gtk.ButtonBox()
        buttonbox.set_layout(Gtk.ButtonBoxStyle.CENTER)
        buttonbox.set_spacing(10)
        buttonbox.pack_start(self._refresh_btn, False, False, 0)
        buttonbox.pack_start(self._connect_btn.align, False, False, 0)

        if self._win.is_plug():
            self._skip_btn = WhiteButton(_("Skip"))
            buttonbox.pack_start(self._skip_btn, False, False, 0)
            self._skip_btn.connect('clicked', self.skip)
        else:
            blank_label = Gtk.Label("")
            buttonbox.pack_start(blank_label, False, False, 0)

        return buttonbox

    # Attached to a callback, hence the extra argument
    def skip(self, skip_btn=None):
        # Exit with an extreme exit code so the init-flow knows the user
        # pressed SKIP
        sys.exit(100)

    def _set_connect_btn_status(self, connect=True):
        self._connect_btn.disconnect(self.connect_handler)

        if connect:
            self.connect_handler = self._connect_btn.connect(
                'clicked', self._first_time_connect
            )
            self._connect_btn.set_color('green')
            self._connect_btn.set_label(_("CONNECT"))

        else:
            self.connect_handler = self._connect_btn.connect(
                'clicked', self._launch_disconnect_thread
            )
            self._connect_btn.set_color('red')
            self._connect_btn.set_label(_("DISCONNECT"))

    def _launch_disconnect_thread(self, widget=None):
        watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
        self._win.get_window().set_cursor(watch_cursor)
        self._connect_btn.start_spinner()
        self._connect_btn.set_sensitive(False)

        # Force the spinner to show on the window.
        while Gtk.events_pending():
            Gtk.main_iteration()

        t = threading.Thread(target=self._threaded_disconnect)
        t.start()

    def _disconnect_screen(self):
        self._win.remove_main_widget()
        title = _("Disconnect complete.")
        description = _("You're now offline")
        buttons = [
            {
                'label': _("CLOSE"),
                'type': 'KanoButton',
                'color': 'red',
                'callback': Gtk.main_quit
            },
            {
                'label': _("CONNECT"),
                'type': 'KanoButton',
                'color': 'green',
                'callback': self._go_to_spinner_screen
            }
        ]
        img_path = os.path.join(img_dir, "no-wifi.png")
        self._win.set_main_widget(
            Template(
                title,
                description,
                buttons,
                self._win.is_plug(),
                img_path
            )
        )

    def _threaded_disconnect(self):
        '''
        This is needed so we can show a spinner while the user is
        disconnecting
        '''
        disconnect(self._wiface)

        def done():
            self._disconnect_screen()
            self._win.get_window().set_cursor(None)
            self._connect_btn.stop_spinner()
            self._connect_btn.set_sensitive(True)

        GObject.idle_add(done)

    def _create_refresh_button(self):
        '''Create the refresh button. This it quite involved as you have
        to pack an image into the button which need to change when the
        cursor hovers over it, and change the cursor to be a
        hand over it.
        '''
        refresh_icon_filepath = os.path.join(img_dir, "refresh.png")
        refresh_icon = Gtk.Image.new_from_file(refresh_icon_filepath)
        refresh_btn = Gtk.Button()
        refresh_btn.get_style_context().add_class('refresh_btn')
        refresh_btn.set_image(refresh_icon)
        attach_cursor_events(refresh_btn)

        # These are here in case we want to change the icon on mouse over
        refresh_btn.connect('enter-notify-event', self._set_refresh_hover_icon)
        refresh_btn.connect('leave-notify-event', self._set_refresh_normal_icon)

        refresh_btn.connect('clicked', self._go_to_spinner_screen)
        return refresh_btn

    # This is linked to enter-notify-event, hence the extra arguments
    def _set_refresh_hover_icon(self, widget=None, event=None):
        '''Change the refresh button's icon to the hover icon.
        '''
        selected_path = os.path.join(img_dir, "rescan-hover.png")
        image = Gtk.Image.new_from_file(selected_path)
        self._refresh_btn.set_image(image)

    # This is linked to leave-notify-event, hence the extra arguments
    def _set_refresh_normal_icon(self, widget=None, event=None):
        '''Change the refresh button's icon to the normal icon.
        '''
        unselected_path = os.path.join(img_dir, "refresh.png")
        image = Gtk.Image.new_from_file(unselected_path)
        self._refresh_btn.set_image(image)

    def _first_time_connect(self, widget=None):
        '''Check the selected network.  If a password is needed,
        take the user to the password screen.  Otherwise, try and connect.
        '''
        if self._selected_network['encryption'] == "off":
            essid = self._selected_network['essid']
            encryption = 'off'
            passphrase = ''
            ConnectToNetwork(self._win, essid, passphrase, encryption)
        else:
            self._go_to_password_screen()

    def _go_to_spinner_screen(self, button=None, event=None):
        '''Loading networks and showing the spinner screen.
        '''

        from kano_wifi_gui.RefreshNetworks import RefreshNetworks
        RefreshNetworks(self._win)

    def _go_to_password_screen(self):
        self._win.remove_main_widget()
        PasswordScreen(self._win, self._wiface,
                       self._selected_network["essid"],
                       self._selected_network["encryption"])

    def _select_network(self, button, network, network_connection):
        for network_btn in self._network_btns:
            network_btn.get_style_context().remove_class('selected')

        network_name = network_connection[0]
        connected = network_connection[3]

        self._selected_network = network
        button.get_style_context().add_class('selected')

        # If we are already connected to this network,
        # offer option to disconnect.
        if network['essid'] == network_name and connected:
            self._set_connect_btn_status(connect=False)
        else:
            self._set_connect_btn_status(connect=True)

        self._connect_btn.set_sensitive(True)

    def _disable_widgets_start_spinner(self):
        self._connect_btn.start_spinner()
        self._disable_widgets()

    def _enable_widgets_stop_spinner(self):
        self._connect_btn.stop_spinner()
        self._enable_widgets()

    def _disable_widgets(self):
        self._set_sensitivity_of_buttons(False)

    def _enable_widgets(self):
        self._connect_btn.stop_spinner()
        self._set_sensitivity_of_buttons(True)

    def _set_sensitivity_of_buttons(self, sensitivity):
        self._connect_btn.set_sensitive(sensitivity)
        self._refresh_btn.set_sensitive(sensitivity)

        # Do we want to block this? Or just make sure the application doesn't
        # fall over afterwards
        if hasattr(self, '_skip_btn'):
            # Skip button should be defined
            self._skip_btn.set_sensitive(sensitivity)
Exemplo n.º 23
0
class SetAccount(Gtk.Box):
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)

        self.win.top_bar.enable_prev()
        self.win.change_prev_callback(self.win.go_to_home)

        self.added_or_removed_account = False

        main_heading = Heading(
            _("System account settings"),
            _("Set your account")
        )

        self.pass_button = KanoButton(_("CHANGE PASSWORD"))
        self.pass_button.pack_and_align()
        self.pass_button.connect('button-release-event', self.go_to_password_screen)
        self.pass_button.connect('key-release-event', self.go_to_password_screen)

        self.add_button = KanoButton(_("ADD ACCOUNT"))
        self.add_button.set_size_request(200, 44)
        self.add_button.connect('button-release-event', self.add_account)
        self.add_button.connect('key-release-event', self.add_account)

        self.remove_button = KanoButton(_("REMOVE ACCOUNT"), color='red')
        self.remove_button.set_size_request(200, 44)
        self.remove_button.connect('button-release-event', self.remove_account_dialog)
        self.remove_button.connect('key-release-event', self.remove_account_dialog)

        button_container = Gtk.Box()
        button_container.pack_start(self.add_button, False, False, 10)
        button_container.pack_start(self.remove_button, False, False, 10)

        button_align = Gtk.Alignment(xscale=0, xalign=0.5)
        button_align.add(button_container)

        accounts_heading = Heading(
            _("Accounts"),
            _("Add or remove accounts")
        )

        # Check if we already scheduled an account add or remove
        # We import kano-init locally to avoid circular dependency
        # the packages.
        try:
            from kano_init.utils import is_any_task_scheduled
            if is_any_task_scheduled():
                self.disable_buttons()
        except ImportError:
            self.disable_buttons()

        self.pack_start(main_heading.container, False, False, 0)
        self.pack_start(self.pass_button.align, False, False, 0)
        self.pack_start(accounts_heading.container, False, False, 0)
        self.pack_start(button_align, False, False, 0)

        self.win.show_all()

    def go_to_password_screen(self, widget, event):

        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            self.win.clear_win()
            SetPassword(self.win)

    # Gets executed when ADD button is clicked
    def add_account(self, widget=None, event=None):
        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            kdialog = None

            try:
                # add new user command
                add_user()
            except UserError as e:
                kdialog = kano_dialog.KanoDialog(
                    _("Error creating new user"),
                    str(e),
                    parent_window=self.win
                )
            else:
                kdialog = kano_dialog.KanoDialog(
                    _("Reboot the system"),
                    _("A new account will be created next time you reboot."),
                    parent_window=self.win
                )

                # Tell user to reboot to see changes
                common.need_reboot = True

            kdialog.run()
            self.disable_buttons()

    # Gets executed when REMOVE button is clicked
    def remove_account_dialog(self, widget=None, event=None):
        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            # Bring in message dialog box
            kdialog = kano_dialog.KanoDialog(
                _("Are you sure you want to delete the current user?"),
                _("You will lose all the data on this account!"),
                [
                    {
                        'label': _("CANCEL"),
                        'color': 'red',
                        'return_value': False
                    },
                    {
                        'label': _("OK"),
                        'color': 'green',
                        'return_value': True
                    }
                ],
                parent_window=self.win
            )
            do_delete_user = kdialog.run()
            if do_delete_user:
                self.disable_buttons()
                try:
                    delete_user()
                except UserError as e:
                    kdialog = kano_dialog.KanoDialog(
                        _("Error deleting user"),
                        str(e),
                        parent_window=self.win
                    )
                    return

                kdialog = kano_dialog.KanoDialog(
                    _("To finish removing this account, you need to reboot"),
                    _("Do you want to reboot?"),
                    [
                        {
                            'label': _("LATER"),
                            'color': 'grey',
                            'return_value': False
                        },
                        {
                            'label': _("REBOOT NOW"),
                            'color': 'orange',
                            'return_value': True
                        }
                    ],
                    parent_window=self.win
                )
                do_reboot_now = kdialog.run()
                if do_reboot_now:
                    os.system("sudo systemctl reboot")

    # Disables both buttons and makes the temp 'flag' folder
    def disable_buttons(self):

        self.add_button.set_sensitive(False)
        self.remove_button.set_sensitive(False)
        self.added_or_removed_account = True
Exemplo n.º 24
0
class SetAccount(Gtk.Box):
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)

        self.win.top_bar.enable_prev()
        self.win.change_prev_callback(self.win.go_to_home)

        self.added_or_removed_account = False

        main_heading = Heading(_("System account settings"),
                               _("Set your account"))

        self.pass_button = KanoButton(_("CHANGE PASSWORD"))
        self.pass_button.pack_and_align()
        self.pass_button.connect('button-release-event',
                                 self.go_to_password_screen)
        self.pass_button.connect('key-release-event',
                                 self.go_to_password_screen)

        self.add_button = KanoButton(_("ADD ACCOUNT"))
        self.add_button.set_size_request(200, 44)
        self.add_button.connect('button-release-event', self.add_account)
        self.add_button.connect('key-release-event', self.add_account)

        self.remove_button = KanoButton(_("REMOVE ACCOUNT"), color='red')
        self.remove_button.set_size_request(200, 44)
        self.remove_button.connect('button-release-event',
                                   self.remove_account_dialog)
        self.remove_button.connect('key-release-event',
                                   self.remove_account_dialog)

        button_container = Gtk.Box()
        button_container.pack_start(self.add_button, False, False, 10)
        button_container.pack_start(self.remove_button, False, False, 10)

        button_align = Gtk.Alignment(xscale=0, xalign=0.5)
        button_align.add(button_container)

        accounts_heading = Heading(_("Accounts"), _("Add or remove accounts"))

        # Check if we already scheduled an account add or remove
        # We import kano-init locally to avoid circular dependency
        # the packages.
        try:
            from kano_init.utils import is_any_task_scheduled
            if is_any_task_scheduled():
                self.disable_buttons()
        except ImportError:
            self.disable_buttons()

        self.pack_start(main_heading.container, False, False, 0)
        self.pack_start(self.pass_button.align, False, False, 0)
        self.pack_start(accounts_heading.container, False, False, 0)
        self.pack_start(button_align, False, False, 0)

        self.win.show_all()

    def go_to_password_screen(self, widget, event):

        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            self.win.clear_win()
            SetPassword(self.win)

    # Gets executed when ADD button is clicked
    def add_account(self, widget=None, event=None):
        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            kdialog = None

            try:
                # add new user command
                add_user()
            except UserError as e:
                kdialog = kano_dialog.KanoDialog(_("Error creating new user"),
                                                 str(e),
                                                 parent_window=self.win)
            else:
                kdialog = kano_dialog.KanoDialog(
                    _("Reboot the system"),
                    _("A new account will be created next time you reboot."),
                    parent_window=self.win)

                # Tell user to reboot to see changes
                common.need_reboot = True

            kdialog.run()
            self.disable_buttons()

    # Gets executed when REMOVE button is clicked
    def remove_account_dialog(self, widget=None, event=None):
        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            # Bring in message dialog box
            kdialog = kano_dialog.KanoDialog(
                _("Are you sure you want to delete the current user?"),
                _("You will lose all the data on this account!"),
                [{
                    'label': _("CANCEL"),
                    'color': 'red',
                    'return_value': False
                }, {
                    'label': _("OK"),
                    'color': 'green',
                    'return_value': True
                }],
                parent_window=self.win)
            do_delete_user = kdialog.run()
            if do_delete_user:
                self.disable_buttons()
                try:
                    delete_user()
                except UserError as e:
                    kdialog = kano_dialog.KanoDialog(_("Error deleting user"),
                                                     str(e),
                                                     parent_window=self.win)
                    return

                kdialog = kano_dialog.KanoDialog(
                    _("To finish removing this account, you need to reboot"),
                    _("Do you want to reboot?"), [{
                        'label': _("LATER"),
                        'color': 'grey',
                        'return_value': False
                    }, {
                        'label': _("REBOOT NOW"),
                        'color': 'orange',
                        'return_value': True
                    }],
                    parent_window=self.win)
                do_reboot_now = kdialog.run()
                if do_reboot_now:
                    os.system("sudo systemctl reboot")

    # Disables both buttons and makes the temp 'flag' folder
    def disable_buttons(self):

        self.add_button.set_sensitive(False)
        self.remove_button.set_sensitive(False)
        self.added_or_removed_account = True
Exemplo n.º 25
0
class ResetPassword(Gtk.Box):

    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_decorated(False)
        self.win.set_main_widget(self)

        self.heading = Heading(
            _("Reset your password"),
            _("We'll send a new password to your email")
        )
        self.pack_start(self.heading.container, False, False, 10)

        self.labelled_entries = LabelledEntries([
            {"heading": _("Email"), "subheading": ""}
        ])
        align = Gtk.Alignment(xscale=0, xalign=0.5)
        self.pack_start(align, False, False, 15)

        self.labelled_entries.set(0, 0, 1, 1)
        self.labelled_entries.set_hexpand(True)

        align.add(self.labelled_entries)

        # Read email from file
        user_email = get_email()

        self.email_entry = self.labelled_entries.get_entry(0)
        self.email_entry.set_text(user_email)
        self.email_entry.connect("key-release-event", self.activate)

        self.button = KanoButton(_("Reset password").upper())
        self.button.pack_and_align()
        self.button.connect("button-release-event", self.activate)
        self.button.connect("key-release-event", self.activate)
        self.button.set_padding(30, 30, 0, 0)

        self.pack_start(self.button.align, False, False, 0)
        self.win.show_all()

    def activate(self, widget, event):
        if not hasattr(event, 'keyval') or event.keyval == 65293:
            watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
            self.win.get_window().set_cursor(watch_cursor)
            self.button.set_sensitive(False)
            self.button.start_spinner()

            thread = threading.Thread(target=self.send_new_password)
            thread.start()

    def send_new_password(self):
        # User may change email
        email = self.labelled_entries.get_entry(0).get_text()
        success, text = reset_password(email)
        if success:
            title = _("Success!")
            description = _("Sent new password to your email")
            button_dict = {
                _("Go to login screen").upper(): {"return_value": 12},
                _("Quit").upper(): {"return_value": 10, "color": "red"}
            }
        else:
            title = _("Something went wrong!")
            description = text
            button_dict = {
                _("Quit").upper(): {"return_value": 10, "color": "red"},
                _("Try again").upper(): {"return_value": 11}
            }

        GObject.idle_add(
            self.finished_thread_cb,
            title,
            description,
            button_dict
        )

    def finished_thread_cb(self, title, description, button_dict):
        kdialog = KanoDialog(
            title,
            description,
            button_dict=button_dict,
            parent_window=self.win
        )
        response = kdialog.run()

        self.win.get_window().set_cursor(None)
        self.button.stop_spinner()
        self.button.set_sensitive(True)

        if response == 10:
            Gtk.main_quit()
        # stay put
        elif response == 11:
            pass
        elif response == 12:
            self.go_to_login_screen()

    def go_to_login_screen(self):
        self.win.remove_main_widget()
        Login(self.win)
Exemplo n.º 26
0
class PasswordScreen(Gtk.Box):
    def __init__(
        self,
        win,
        wiface,
        network_name,
        encryption,
        wrong_password=False
    ):

        '''
        Show the screen with the option of adding a password
        and connecting to a network
        '''

        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self._win = win
        self._win.set_main_widget(self)
        self._win.top_bar.enable_prev()
        self._wiface = wiface
        self._network_name = network_name
        self._encryption = encryption

        # Keep track if the user has already entered the wrong password before
        # so that we only pack the "password incorrect" label once
        self._wrong_password_used_before = False

        self._heading = Heading(
            "Connect to the network",
            self._network_name,
            self._win.is_plug(),
            True
        )

        self._heading.set_prev_callback(self._refresh_networks)
        self._heading.container.set_margin_right(20)
        self._heading.container.set_margin_left(20)

        if wrong_password:
            image_path = os.path.join(img_dir, "password-fail.png")
            wrong_password = self._create_wrong_password_label()
            self._heading.container.pack_start(wrong_password, True, True, 0)
        else:
            image_path = os.path.join(img_dir, "password.png")

        self._padlock_image = Gtk.Image.new_from_file(image_path)

        self._password_entry = Gtk.Entry()
        self._password_entry.set_placeholder_text("Password")
        self._password_entry.set_visibility(False)
        self._password_entry.get_style_context().add_class("password_entry")
        self._password_entry.set_margin_left(60)
        self._password_entry.set_margin_right(60)
        self._password_entry.connect("key-release-event",
                                     self._set_button_sensitive)
        # If Enter key is pressed on the password entry, we want to act as
        # though the connect_btn was clicked
        self._password_entry.connect(
            "key-release-event", self._on_connect_key_wrapper
        )

        self._connect_btn = KanoButton("CONNECT")
        self._connect_btn.connect('clicked', self._on_connect)
        self._connect_btn.set_sensitive(False)
        self._connect_btn.set_margin_right(100)
        self._connect_btn.set_margin_left(100)
        self._connect_btn.pack_and_align()

        self._show_password = Gtk.CheckButton.new_with_label("Show password")
        self._show_password.get_style_context().add_class("show_password")
        self._show_password.connect("toggled",
                                    self._change_password_entry_visiblity)
        self._show_password.set_active(True)
        self._show_password.set_margin_left(100)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.add(vbox)

        vbox.pack_start(self._heading.container, False, False, 10)
        vbox.pack_start(self._padlock_image, False, False, 10)
        vbox.pack_start(self._password_entry, False, False, 10)
        vbox.pack_start(self._show_password, False, False, 10)
        vbox.pack_end(self._connect_btn.align, False, False, 40)

        # Entry should have the keyboard focus
        self._password_entry.grab_focus()

        self.show_all()

    def _create_wrong_password_label(self):
        label = Gtk.Label("Password incorrect")
        label.get_style_context().add_class("wrong_password_label")
        return label

    def _change_password_entry_visiblity(self, widget):
        '''
        Depending on the checkbox, change the writing in the
        password entry to be readable.
        '''
        visibility = self._show_password.get_active()
        self._password_entry.set_visibility(visibility)

    def _refresh_networks(self, widget=None):
        from kano_wifi_gui.RefreshNetworks import RefreshNetworks
        RefreshNetworks(self._win)

    def _on_connect_key_wrapper(self, widget, event):
        if event.keyval == Gdk.KEY_Return:
            self._on_connect()

    def _on_connect(self, widget=None):
        passphrase = self._password_entry.get_text()
        ConnectToNetwork(
            self._win,
            self._network_name,
            passphrase,
            self._encryption
        )

    def _set_button_sensitive(self, widget, event):
        self._connect_btn.set_sensitive(True)

    def _thread_finish(self, success):

        if success:
            self._success_screen()
        else:
            self._wrong_password_screen()

    def _success_screen(self):
        self._win.remove_main_widget()

        title = "Success!"
        description = "You're connected"
        buttons = [
            {
                "label": "OK",
                "color": "green",
                "type": "KanoButton",
                "callback": Gtk.main_quit
            }
        ]
        img_path = os.path.join(img_dir, "internet.png")

        self._win.set_main_widget(
            Template(
                title,
                description,
                buttons,
                self._win.is_plug(),
                img_path
            )
        )

    def _disable_widgets_start_spinner(self):
        self._connect_btn.start_spinner()
        self._connect_btn.set_sensitive(False)
        self._win.top_bar.prev_button.set_sensitive(False)
        self._password_entry.set_sensitive(False)
        self._show_password.set_sensitive(False)

    def _enable_widgets_stop_spinner(self):
        self._connect_btn.stop_spinner()
        self._connect_btn.set_sensitive(True)
        self._win.top_bar.prev_button.set_sensitive(True)
        self._password_entry.set_sensitive(True)
        self._show_password.set_sensitive(True)
Exemplo n.º 27
0
class OverscanTemplate(Gtk.Box):
    def __init__(self, win, title, description, original_overscan=None):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.kano_button = KanoButton("APPLY CHANGES")
        self.kano_button.connect("button-release-event", self.apply_changes)
        self.kano_button.pack_and_align()

        self.heading = Heading(title, description)
        self.pack_start(self.heading.container, False, False, 0)

        self.win = win
        self.win.set_main_widget(self)

        self.win.top_bar.enable_prev()

        # Launch pipe for the overscan c code
        launch_pipe()

        self.overscan_values = get_overscan_status()
        self.original_overscan = original_overscan

        # Pass original overscan values between the classes
        # If original_overscan hasn't been generated yet, get it from current overscan status
        # Alternatively, maybe read this from a file in future
        if original_overscan is None:
            self.original_overscan = get_overscan_status()

        # Reset button
        self.reset_button = OrangeButton()
        reset_image = Gtk.Image().new_from_file(common.media + "/Icons/reset.png")
        self.reset_button.set_image(reset_image)
        self.reset_button.connect("button_press_event", self.reset)

    def apply_changes(self, button, event):
        # Apply changes
        write_overscan_values(self.overscan_values)
        self.original_overscan = self.overscan_values
        set_config_comment('kano_screen_used', get_model())

        # Tell user to reboot to see changes
        common.need_reboot = True

        self.go_to_display()

    def adjust(self, adj, varname):
        self.overscan_values[varname] = int(adj.get_value())
        set_overscan_status(self.overscan_values)

    def adjust_all(self, adj):
        self.overscan_values['top'] = int(adj.get_value())
        self.overscan_values['bottom'] = int(adj.get_value())
        self.overscan_values['left'] = int(adj.get_value())
        self.overscan_values['right'] = int(adj.get_value())
        set_overscan_status(self.overscan_values)

    def go_to_display(self, widget=None, button=None):
        self.reset()
        self.win.clear_win()
        SetDisplay(self.win)

    def reset(self, widget=None, event=None):
        pass
Exemplo n.º 28
0
class OverscanTemplate(Gtk.Box):
    def __init__(self, win, title, description, original_overscan=None):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.kano_button = KanoButton(_("APPLY CHANGES"))
        self.kano_button.connect('button-release-event', self.apply_changes)
        self.kano_button.pack_and_align()

        self.heading = Heading(title, description)
        self.pack_start(self.heading.container, False, False, 0)

        self.win = win
        self.win.set_main_widget(self)

        self.win.top_bar.enable_prev()

        # Launch pipe for the overscan c code
        launch_pipe()

        self.overscan_values = get_overscan_status()
        self.original_overscan = original_overscan

        # Pass original overscan values between the classes
        # If original_overscan hasn't been generated yet, get it from current
        # overscan status. Alternatively, maybe read this from a file in future
        if original_overscan is None:
            self.original_overscan = get_overscan_status()

        # Reset button
        self.reset_button = OrangeButton()
        reset_icon_path = os.path.join(common.media, '/Icons/reset.png')
        reset_image = Gtk.Image().new_from_file(reset_icon_path)
        self.reset_button.set_image(reset_image)
        self.reset_button.connect('button_press_event', self.reset)

    def apply_changes(self, button, event):
        # NB, write_overscan_values ends the transaction
        write_overscan_values(self.overscan_values)
        self.original_overscan = self.overscan_values

        # Tell user to reboot to see changes
        common.need_reboot = True

        self.go_to_display()

    def adjust(self, adj, varname):
        self.overscan_values[varname] = int(adj.get_value())
        set_overscan_status(self.overscan_values)

    def adjust_all(self, adj):
        self.overscan_values['top'] = int(adj.get_value())
        self.overscan_values['bottom'] = int(adj.get_value())
        self.overscan_values['left'] = int(adj.get_value())
        self.overscan_values['right'] = int(adj.get_value())
        set_overscan_status(self.overscan_values)

    def go_to_display(self, widget=None, button=None):
        self.reset()
        self.win.clear_win()
        SetDisplay(self.win)

    def reset(self, widget=None, event=None):
        pass
Exemplo n.º 29
0
class SetAbout(Gtk.Box):
    selected_button = 0
    initial_button = 0

    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

        self.win = win
        self.win.set_main_widget(self)
        self.win.top_bar.enable_prev()
        self.win.change_prev_callback(self.win.go_to_home)

        image = Gtk.Image.new_from_file(media + "/Graphics/about-screen.png")

        version_number, os_name = get_current_version()
        os_variant = read_file_contents('/etc/kanux_version_variant')

        version_align = self.create_align(
            "Kano OS: {name} v{version}".format(name=os_name, version=version_number),
            'about_version'
        )
        if os_variant:
            variant_align = self.create_align(
                "{variant}".format(variant=os_variant),
                'about_version'
            )
        space_align = self.create_align(
            _("Disk space used: {used}B / {total}B").format(**get_space_available())
        )
        try:
            celsius = u"{:.1f}\N{DEGREE SIGN}C".format(get_temperature())
        except ValueError:
            celsius = "?"
        temperature_align = self.create_align(
            _(u"Temperature: {celsius}").format(celsius=celsius)
        )
        model_align = self.create_align(
            _("Model: {model}").format(model=get_model_name())
        )

        terms_and_conditions = OrangeButton(_("Terms and conditions"))
        terms_and_conditions.connect(
            'button_release_event', self.show_terms_and_conditions
        )

        credits_button = OrangeButton(_("Meet the team"))
        credits_button.connect(
            'button_release_event', self.show_credits
        )

        self.kano_button = KanoButton(_("BACK"))
        self.kano_button.pack_and_align()

        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        hbox.pack_start(terms_and_conditions, False, False, 4)
        hbox.pack_start(credits_button, False, False, 4)
        hbutton_container = Gtk.Alignment(
            xalign=0.5, xscale=0, yalign=0, yscale=0
        )
        hbutton_container.add(hbox)

        image.set_margin_top(10)
        self.pack_start(image, False, False, 10)
        self.pack_start(version_align, False, False, 2)
        if os_variant:
            self.pack_start(variant_align, False, False, 2)
        self.pack_start(space_align, False, False, 1)
        self.pack_start(temperature_align, False, False, 1)
        self.pack_start(model_align, False, False, 1)
        self.pack_start(hbutton_container, False, False, 3)
        self.pack_start(self.kano_button.align, False, False, 10)

        self.kano_button.connect('button-release-event', self.win.go_to_home)
        self.kano_button.connect('key-release-event', self.win.go_to_home)

        # Refresh window
        self.win.show_all()

    def create_align(self, text, css_class='about_label'):
        '''This styles the status information in the 'about' dialog
        '''

        label = Gtk.Label(text)
        label.get_style_context().add_class(css_class)

        align = Gtk.Alignment(xalign=0.5, xscale=0, yalign=0, yscale=0)
        align.add(label)

        return align

    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_credits(self, widget, event):
        '''Launch the credits
        '''

        os.system(
            "/usr/bin/kano-launcher \"kdesk-blur 'urxvt -bg "
            "rgba:0000/0000/0000/FFFF -title 'Credits' -e "
            "/usr/bin/kano-credits'\""
        )