Exemplo n.º 1
0
    def second_scroll(self):
        self._clear()
        ticks = Gtk.Image.new_from_file(self._stage.media_path('ticks.png'))

        copy = [
            "Complete all of the ticks in a",
            "quest to unlock rewards."
        ]
        text_widgets = self._get_text_widgets(copy)

        chest = Gtk.Image.new_from_file(self._stage.media_path('chest-open.png'))

        button = KanoButton('NEXT', color='orange')
        button.connect('clicked', cb_wrapper, self.third_scroll)

        ticks.set_margin_top(20)
        self._vbox.pack_start(ticks, False, False, 0)

        text_widgets[0].set_margin_top(40)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        chest.set_margin_top(35)
        self._vbox.pack_start(chest, False, False, 0)

        button.set_margin_top(40)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
Exemplo n.º 2
0
    def third_scroll(self):
        self._clear()

        heading = Gtk.Label('New quest')
        add_class(heading, 'scroll-heading')

        world = Gtk.Image.new_from_file(self._stage.media_path('world.png'))

        copy = [
            "Journey to Kano World",
        ]
        text_widgets = self._get_text_widgets(copy)

        button = KanoButton('OK', color='orange')
        button.connect('clicked', cb_wrapper, self._stage._ctl.next_stage)

        heading.set_margin_top(35)
        self._vbox.pack_start(heading, False, False, 0)

        world.set_margin_top(35)
        self._vbox.pack_start(world, False, False, 0)

        text_widgets[0].set_margin_top(40)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        button.set_margin_top(40)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
Exemplo n.º 3
0
    def first_scroll(self):
        self._clear()
        copy = [
            "Quests are a series of tasks that you",
            "can complete on your Kano to get",
            "great rewards."
        ]
        text_widgets = self._get_text_widgets(copy)

        img_path = self._stage.media_path('chest-closed.png')
        chest = Gtk.Image.new_from_file(img_path)

        button = KanoButton('NEXT', color='orange')
        button.connect('clicked', cb_wrapper, self.second_scroll)

        text_widgets[0].set_margin_top(30)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        chest.set_margin_top(60)
        self._vbox.pack_start(chest, False, False, 0)

        button.set_margin_top(70)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
Exemplo n.º 4
0
    def __generate_buttons(self):
        self.buttons = []
        kano_button_box = Gtk.Box()

        for button in self.button_info:
            for argument, value in button_defaults.iteritems():

                # Use default info if not provided
                if argument not in button:
                    button[argument] = value

                    # Create default return values for OK and CANCEL buttons
                    if argument == "return_value":
                        if hasattr(button, "label"):
                            if button["label"] == _("OK"):
                                button["return_value"] = 0
                            elif button["label"] == _("CANCEL"):
                                button["return_value"] = 1
                    if argument == "color":
                        if button["label"] == _("CANCEL"):
                            button["color"] = "red"

            color = button["color"]
            return_value = button["return_value"]
            button_name = button["label"]

            button = KanoButton(button_name)
            button.set_color(color)
            button.connect("button-release-event", self.exit_dialog, return_value)
            button.connect("key-release-event", self.exit_dialog, return_value)
            self.buttons.append(button)
            kano_button_box.pack_start(button, False, False, 6)

        return kano_button_box
Exemplo n.º 5
0
    def slide1(self):
        fixed = Gtk.Fixed()

        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
            self.media_path("apps-slide.png"),
            1000,
            678
        )
        image = Gtk.Image.new_from_pixbuf(pixbuf)
        title1 = Gtk.Label("Get Started")
        title1.get_style_context().add_class("title")
        title2 = Gtk.Label("Apps")
        title2.get_style_context().add_class("title")
        desc = Gtk.Label(
            "Create and play with\n" +
            "Kano's Apps to make and save your\n" +
            "own code masterpieces, from games\n" +
            "and minecraft world, to art and music pieces..."
        )
        desc.get_style_context().add_class("description")

        next_button = KanoButton("NEXT")
        next_button.connect("clicked", self.slide2_wrapper)

        fixed.put(image, 0, 0)
        fixed.put(title1, 460, 40)
        fixed.put(title2, 60, 400)
        fixed.put(desc, 60, 450)
        fixed.put(next_button, 460, 580)

        self.add(fixed)

        self.show_all()
Exemplo n.º 6
0
    def first_scroll(self):
        self._clear()
        copy = [
            "Quests are a series of tasks that you",
            "can complete on your Kano to get", "great rewards."
        ]
        text_widgets = self._get_text_widgets(copy)

        img_path = self._stage.media_path('chest-closed.png')
        chest = Gtk.Image.new_from_file(img_path)

        button = KanoButton('NEXT', color='orange')
        button.connect('clicked', cb_wrapper, self.second_scroll)

        text_widgets[0].set_margin_top(30)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        chest.set_margin_top(60)
        self._vbox.pack_start(chest, False, False, 0)

        button.set_margin_top(70)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
Exemplo n.º 7
0
    def __init__(self, stage, overscan_ctl, next_cb):
        super(Window2, self).__init__()

        add_class(self, 'overscan-window')

        head_img = Gtk.Image.new_from_file(stage.media_path('hint2.png'))
        box = Gtk.VBox()
        self.add(box)

        box.pack_start(head_img, False, False, 0)

        heading = Gtk.Label('Use UP and DOWN keys')
        heading.set_margin_top(25)
        heading.set_margin_bottom(25)
        add_class(heading, 'notebook-heading')
        box.pack_start(heading, False, False, 0)

        label_copy = 'Stretch or shrink your screen, until the white lines'
        text1 = Gtk.Label(label_copy)
        text1.set_margin_bottom(5)
        add_class(text1, 'notebook-text')
        box.pack_start(text1, False, False, 0)

        text2 = Gtk.Label('are lined up with the edges')
        text2.set_margin_bottom(25)
        add_class(text2, 'notebook-text')
        box.pack_start(text2, False, False, 0)

        buttons = Gtk.HBox(halign=Gtk.Align.CENTER)
        buttons.set_margin_bottom(25)
        done = KanoButton('DONE', color='green')
        buttons.pack_start(done, False, False, 0)
        done.connect('clicked', cb_wrapper, next_cb)

        box.pack_start(buttons, False, False, 0)
Exemplo n.º 8
0
    def second_scroll(self):
        self._clear()
        ticks = Gtk.Image.new_from_file(self._stage.media_path('ticks.png'))

        copy = ["Complete all of the ticks in a", "quest to unlock rewards."]
        text_widgets = self._get_text_widgets(copy)

        chest = Gtk.Image.new_from_file(
            self._stage.media_path('chest-open.png'))

        button = KanoButton('NEXT', color='orange')
        button.connect('clicked', cb_wrapper, self.third_scroll)

        ticks.set_margin_top(20)
        self._vbox.pack_start(ticks, False, False, 0)

        text_widgets[0].set_margin_top(40)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        chest.set_margin_top(35)
        self._vbox.pack_start(chest, False, False, 0)

        button.set_margin_top(40)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
    def __init__(self, win, char_creator):
        Gtk.EventBox.__init__(self)

        self._win = win

        # Should this be inherited, passed as a variable, or global?
        # Could be a member variable in window.
        # self.char_creator = self._win.get_char_creator()
        self.char_creator = char_creator
        self._win.pack_in_main_content(self.char_creator)
        self.char_creator.reset_selected_menu_items()

        save_changes_button = KanoButton(_("Save changes").upper())
        save_changes_button.connect("clicked", self.save_changes)

        discard_changes_button = OrangeButton(_("Discard").upper())
        discard_changes_button.connect("clicked", self.discard)
        discard_changes_button.set_margin_left(100)
        empty_label = Gtk.Label("")

        button_box = Gtk.ButtonBox()
        button_box.pack_start(discard_changes_button, False, False, 0)
        button_box.pack_start(save_changes_button, False, False, 0)
        button_box.pack_start(empty_label, False, False, 0)

        self._win.pack_in_bottom_bar(button_box)
        self._win.show_all()

        # Hide all the pop ups
        self.char_creator._hide_pop_ups()
Exemplo n.º 10
0
    def __init__(self, stage, troubleshoot_cb, skip_cb):
        super(TroubleshootOrDisconnect,
              self).__init__(orientation=Gtk.Orientation.VERTICAL)

        self._stage = stage

        self.set_hexpand(False)
        self.set_vexpand(False)
        self.set_margin_left(40)
        self.set_margin_right(40)

        desc = Gtk.Label('Oops there was a problem connecting to internet.')
        desc.set_line_wrap(True)
        add_class(desc, 'console-screen-desc')

        img_path = self._stage.media_path("troubleshooting.png")
        image = Gtk.Image.new_from_file(img_path)

        troubleshoot = KanoButton('FIX IT')
        troubleshoot.connect('clicked', self._cb_wrapper, troubleshoot_cb)

        skip = KanoButton('SKIP', color="orange")
        skip.connect('clicked', self._cb_wrapper, skip_cb)

        buttons = Gtk.HBox(False, 0)
        buttons.pack_start(troubleshoot, True, True, 20)
        buttons.pack_start(skip, True, True, 0)

        self.pack_start(desc, False, False, 40)
        self.pack_start(image, False, False, 20)
        self.pack_start(buttons, False, False, 30)
Exemplo n.º 11
0
class KanoButtonBox(Gtk.Box):

    def __init__(self, kano_button_text, orange_text="", orange_text_2=""):

        Gtk.Box.__init__(self)
        self.kano_button = KanoButton(kano_button_text)

        if not orange_text == "":
            self.orange_button = OrangeButton(orange_text)
            self.pack_start(self.orange_button, False, False, 0)
            self.pack_start(self.kano_button, False, False, 0)

            if orange_text_2 == "":
                # The empty label is to centre the kano_button
                label = Gtk.Label("    ")
                self.pack_start(label, False, False, 0)
            else:
                self.orange_button2 = OrangeButton(orange_text_2)
                self.pack_start(self.orange_button2, False, False, 0)
        else:
            self.pack_start(self.kano_button, False, False, 0)

    def get_kano_button(self):
        return self.kano_button

    def set_kano_button_cb(self, cb, args=[]):
        self.kano_button.connect('button-release-event', cb, args)

    def set_orange_button_cb(self, cb, args=[]):
        self.orange_button.connect('button-release-event', cb, args)

    def set_orange_button2_cb(self, cb, args=None):
        self.orange_button2.connect('button-release-event', cb, args)
Exemplo n.º 12
0
    def __generate_buttons(self):
        self.buttons = []
        kano_button_box = Gtk.Box()

        for button in self.button_info:
            for argument, value in button_defaults.iteritems():

                # Use default info if not provided
                if argument not in button:
                    button[argument] = value

                    # Create default return values for OK and CANCEL buttons
                    if argument == 'return_value':
                        if hasattr(button, 'label'):
                            if button['label'] == _("OK"):
                                button['return_value'] = 0
                            elif button['label'] == _("CANCEL"):
                                button['return_value'] = 1
                    if argument == 'color':
                        if button['label'] == _("CANCEL"):
                            button['color'] = 'red'

            color = button['color']
            return_value = button['return_value']
            button_name = button['label']

            button = KanoButton(button_name)
            button.set_color(color)
            button.connect('button-release-event', self.exit_dialog,
                           return_value)
            button.connect('key-release-event', self.exit_dialog, return_value)
            self.buttons.append(button)
            kano_button_box.pack_start(button, False, False, 6)

        return kano_button_box
Exemplo n.º 13
0
    def third_scroll(self):
        self._clear()

        heading = Gtk.Label('New quest')
        add_class(heading, 'scroll-heading')

        world = Gtk.Image.new_from_file(self._stage.media_path('world.png'))

        copy = [
            "Journey to Kano World",
        ]
        text_widgets = self._get_text_widgets(copy)

        button = KanoButton('OK', color='orange')
        button.connect('clicked', cb_wrapper, self._stage._ctl.next_stage)

        heading.set_margin_top(35)
        self._vbox.pack_start(heading, False, False, 0)

        world.set_margin_top(35)
        self._vbox.pack_start(world, False, False, 0)

        text_widgets[0].set_margin_top(40)
        for w in text_widgets:
            self._vbox.pack_start(w, False, False, 0)

        button.set_margin_top(40)
        button.set_margin_left(80)
        button.set_margin_right(80)
        self._vbox.pack_start(button, False, False, 0)

        self.show_all()
Exemplo n.º 14
0
    def __init__(self, stage, try_again_cb, skip_cb):
        super(AreYouSure, self).__init__(orientation=Gtk.Orientation.VERTICAL)

        self._stage = stage

        self.set_hexpand(False)
        self.set_vexpand(False)
        self.set_margin_left(40)
        self.set_margin_right(40)

        heading = Gtk.Label('Are You Sure?')
        heading.set_margin_top(20)
        add_class(heading, 'console-screen-heading')

        desc = Gtk.Label("Kano uses WiFi to stay up to date" +
                         "\nwith all new software updates, apps" +
                         "\nand features.")
        desc.set_justify(Gtk.Justification.CENTER)
        desc.set_line_wrap(True)
        add_class(desc, 'console-screen-desc')

        try_again = KanoButton('TRY AGAIN')
        try_again.connect('clicked', self._cb_wrapper, try_again_cb)

        skip = KanoButton('YES I WANT TO SKIP', color="grey")
        skip.connect('clicked', self._cb_wrapper, skip_cb,
                     'init-flow-wifi-skipped')

        buttons = Gtk.HBox(False, 0)
        buttons.pack_start(try_again, True, True, 20)
        buttons.pack_start(skip, True, True, 0)

        self.pack_start(heading, False, False, 30)
        self.pack_start(desc, False, False, 40)
        self.pack_start(buttons, False, False, 40)
Exemplo n.º 15
0
    def slide2(self):
        self.clear_window()
        fixed = Gtk.Fixed()

        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
            self.media_path("world-slide.png"),
            1000,
            678
        )
        image = Gtk.Image.new_from_pixbuf(pixbuf)
        title = Gtk.Label("Kano World")
        title.get_style_context().add_class("title")
        desc = Gtk.Label(
            "Show off and share your creations to friends\n" +
            "family and other Kano users on Kano World.\n\n" +
            "Why not check it out now by clicking on the\n" +
            "icon to see what people have made today."
        )
        desc.get_style_context().add_class("description")

        next_button = KanoButton("LET'S GO")
        next_button.connect("clicked", Gtk.main_quit)

        fixed.put(image, 0, 0)
        fixed.put(title, 415, 370)
        fixed.put(desc, 310, 420)
        fixed.put(next_button, 440, 580)

        self.add(fixed)

        self.show_all()
Exemplo n.º 16
0
    def __init__(self, stage, yes_cb, no_cb):
        super(Window1, self).__init__()

        add_class(self, 'overscan-window')

        head_img = Gtk.Image.new_from_file(stage.media_path('hint1.png'))
        box = Gtk.VBox()
        self.add(box)

        box.pack_start(head_img, False, False, 0)

        heading = Gtk.Label('Let\'s set up your screen')
        heading.set_margin_top(25)
        heading.set_margin_bottom(25)
        add_class(heading, 'notebook-heading')
        box.pack_start(heading, False, False, 0)

        heading = Gtk.Label('Are the white lines touching the edges?')
        heading.set_margin_bottom(35)
        add_class(heading, 'notebook-text')
        box.pack_start(heading, False, False, 0)

        buttons = Gtk.HBox(halign=Gtk.Align.CENTER)
        buttons.set_margin_bottom(25)
        yes = KanoButton('YES', color='green')
        yes.connect('clicked', cb_wrapper, yes_cb)
        buttons.pack_start(yes, False, False, 0)
        no = KanoButton('NO', color='red')
        no.connect('clicked', cb_wrapper, no_cb)
        buttons.pack_start(no, False, False, 10)

        box.pack_start(buttons, False, False, 0)
Exemplo n.º 17
0
class CharacterEdit(Gtk.EventBox):
    '''Offer the user the option to modify their avatar
    '''

    def __init__(self, win, char_creator):
        Gtk.EventBox.__init__(self)

        self._win = win

        # Should this be inherited, passed as a variable, or global?
        # Could be a member variable in window.
        # self.char_creator = self._win.get_char_creator()
        self.char_creator = char_creator
        self._win.pack_in_main_content(self.char_creator)
        self.char_creator.reset_selected_menu_items()

        self._save_changes_button = KanoButton(_("Save changes").upper())
        self._save_changes_button.connect('clicked', self.save_changes)
        self._save_changes_button.set_sensitive(False)

        self.char_creator.connect(
            'character_changed',
            self._make_button_sensitive
        )

        discard_changes_button = OrangeButton(_("Discard").upper())
        discard_changes_button.connect('clicked', self.discard)
        discard_changes_button.set_margin_left(100)
        empty_label = Gtk.Label("")

        button_box = Gtk.ButtonBox()
        button_box.pack_start(discard_changes_button, False, False, 0)
        button_box.pack_start(self._save_changes_button, False, False, 0)
        button_box.pack_start(empty_label, False, False, 0)

        self._win.pack_in_bottom_bar(button_box)
        self._win.show_all()

        # Hide all the pop ups
        self.char_creator._hide_pop_ups()

    def save_changes(self, widget):
        self.char_creator.save()
        self._go_back_to_display_screen()

    def discard(self, widget):
        self.char_creator.update_from_saved_image()
        self._go_back_to_display_screen()

    def _go_back_to_display_screen(self):
        '''Don't save, just go back to the edit character screen
        '''
        self._win.empty_main_content()
        self._win.empty_bottom_bar()
        self._win.menu_bar.enable_buttons()
        CharacterDisplay(self._win)

    def _make_button_sensitive(self, widget=None):
        self._save_changes_button.set_sensitive(True)
Exemplo n.º 18
0
    def __init__(self, stage, image_path, image_scale, image_align, title,
                 copy, buttons):
        super(Notebook, self).__init__()

        self.add(
            Gtk.Image.new_from_file(stage.media_path('lonely-notebook.png')))

        fixed = Gtk.Fixed()
        self.add_overlay(fixed)

        self._eb = Gtk.EventBox()
        add_class(self._eb, 'notebook-content-area')
        self._eb.set_size_request(415, 460)

        fixed.put(self._eb, 20, 70)

        vbox = Gtk.VBox(False, 0)
        vbox.set_vexpand(True)
        vbox.set_hexpand(True)
        vbox.set_margin_left(10)
        vbox.set_margin_right(10)

        img = scale_image(Gtk.Image.new_from_file(image_path), image_scale)
        img_align = Gtk.Alignment.new(image_align, 0.5, 0, 0)
        img_align.add(img)
        img_align.set_vexpand(True)
        img_align.set_hexpand(True)
        vbox.pack_start(img_align, False, False, 0)

        heading = Gtk.Label(title)
        add_class(heading, 'notebook-heading')

        copy_widgets = []
        for line in copy:
            l = Gtk.Label(line)
            l.set_line_wrap(False)
            l.set_justify(Gtk.Justification.CENTER)
            add_class(l, 'notebook-text')
            l.set_halign(Gtk.Align.CENTER)
            copy_widgets.append(l)

        # Pack heading
        vbox.pack_start(heading, False, False, 0)
        heading.set_margin_top(15)
        heading.set_margin_bottom(15)

        for w in copy_widgets:
            vbox.pack_start(w, False, False, 3)

        hbox = Gtk.HBox(False, 10)
        hbox.set_margin_top(15)
        hbox.set_halign(Gtk.Align.CENTER)
        for b in buttons:
            button = KanoButton(b['label'], color=b['color'])
            button.connect('clicked', cb_wrapper, b['callback'])
            hbox.pack_start(button, False, False, 0)
        vbox.pack_start(hbox, False, False, 0)

        self._eb.add(vbox)
Exemplo n.º 19
0
    def __init__(self, stage, image_path, image_scale, image_align,
                 title, copy, buttons):
        super(Notebook, self).__init__()

        self.add(Gtk.Image.new_from_file(stage.media_path('lonely-notebook.png')))

        fixed = Gtk.Fixed()
        self.add_overlay(fixed)

        self._eb = Gtk.EventBox()
        add_class(self._eb, 'notebook-content-area')
        self._eb.set_size_request(415, 460)

        fixed.put(self._eb, 20, 70)

        vbox = Gtk.VBox(False, 0)
        vbox.set_vexpand(True)
        vbox.set_hexpand(True)
        vbox.set_margin_left(10)
        vbox.set_margin_right(10)

        img = scale_image(Gtk.Image.new_from_file(image_path), image_scale)
        img_align = Gtk.Alignment.new(image_align, 0.5, 0, 0)
        img_align.add(img)
        img_align.set_vexpand(True)
        img_align.set_hexpand(True)
        vbox.pack_start(img_align, False, False, 0)

        heading = Gtk.Label(title)
        add_class(heading, 'notebook-heading')

        copy_widgets = []
        for line in copy:
            l = Gtk.Label(line)
            l.set_line_wrap(False)
            l.set_justify(Gtk.Justification.CENTER)
            add_class(l, 'notebook-text')
            l.set_halign(Gtk.Align.CENTER)
            copy_widgets.append(l)

        # Pack heading
        vbox.pack_start(heading, False, False, 0)
        heading.set_margin_top(15)
        heading.set_margin_bottom(15)

        for w in copy_widgets:
            vbox.pack_start(w, False, False, 3)

        hbox = Gtk.HBox(False, 10)
        hbox.set_margin_top(15)
        hbox.set_halign(Gtk.Align.CENTER)
        for b in buttons:
            button = KanoButton(b['label'], color=b['color'])
            button.connect('clicked', cb_wrapper, b['callback'])
            hbox.pack_start(button, False, False, 0)
        vbox.pack_start(hbox, False, False, 0)

        self._eb.add(vbox)
Exemplo n.º 20
0
class CharacterEdit(Gtk.EventBox):
    '''Offer the user the option to modify their avatar
    '''
    def __init__(self, win, char_creator):
        Gtk.EventBox.__init__(self)

        self._win = win

        # Should this be inherited, passed as a variable, or global?
        # Could be a member variable in window.
        # self.char_creator = self._win.get_char_creator()
        self.char_creator = char_creator
        self._win.pack_in_main_content(self.char_creator)
        self.char_creator.reset_selected_menu_items()

        self._save_changes_button = KanoButton(_("Save changes").upper())
        self._save_changes_button.connect('clicked', self.save_changes)
        self._save_changes_button.set_sensitive(False)

        self.char_creator.connect('character_changed',
                                  self._make_button_sensitive)

        discard_changes_button = OrangeButton(_("Discard").upper())
        discard_changes_button.connect('clicked', self.discard)
        discard_changes_button.set_margin_left(100)
        empty_label = Gtk.Label("")

        button_box = Gtk.ButtonBox()
        button_box.pack_start(discard_changes_button, False, False, 0)
        button_box.pack_start(self._save_changes_button, False, False, 0)
        button_box.pack_start(empty_label, False, False, 0)

        self._win.pack_in_bottom_bar(button_box)
        self._win.show_all()

        # Hide all the pop ups
        self.char_creator._hide_pop_ups()

    def save_changes(self, widget):
        self.char_creator.save()
        self._go_back_to_display_screen()

    def discard(self, widget):
        self.char_creator.update_from_saved_image()
        self._go_back_to_display_screen()

    def _go_back_to_display_screen(self):
        '''Don't save, just go back to the edit character screen
        '''
        self._win.empty_main_content()
        self._win.empty_bottom_bar()
        self._win.menu_bar.enable_buttons()
        CharacterDisplay(self._win)

    def _make_button_sensitive(self, widget=None):
        self._save_changes_button.set_sensitive(True)
Exemplo n.º 21
0
    def __init__(self, title, description, buttons, is_plug=False, img_path=None):
        super(Template, self).__init__(orientation=Gtk.Orientation.VERTICAL)
        self._focus_widget = None

        heading = Heading(
            title,
            description,
            is_plug,
            back_btn=False
        )
        bbox = Gtk.ButtonBox()
        bbox.set_spacing(20)
        bbox.set_layout(Gtk.ButtonBoxStyle.CENTER)
        bbox.set_margin_right(10)
        bbox.set_margin_left(10)

        for b in buttons:
            label = b["label"]

            if not label:
                gtk_button = Gtk.Label()

            else:
                button_type = b["type"]
                callback = b["callback"]

                if button_type == "KanoButton":
                    color = b["color"]
                    gtk_button = KanoButton(label, color=color)
                elif button_type == "OrangeButton":
                    gtk_button = OrangeButton(label)

                gtk_button.connect("clicked", callback)
            bbox.pack_start(gtk_button, False, False, 0)

            if "focus" in b:
                self._focus_widget = gtk_button

        self.pack_start(heading.container, False, False, 0)
        heading.container.set_margin_right(15)
        heading.container.set_margin_left(15)

        if img_path:
            image = Gtk.Image.new_from_file(img_path)

        if is_plug:
            self.pack_start(image, False, False, 10)
            self.pack_start(bbox, False, False, 30)
        else:
            self.pack_start(image, False, False, 20)
            self.pack_end(bbox, False, False, 30)

        self.show_all()
Exemplo n.º 22
0
class NewUserView(Gtk.Grid):

    def __init__(self, greeter):
        Gtk.Grid.__init__(self)

        self.get_style_context().add_class('password')
        self.set_row_spacing(12)

        self.greeter = greeter

        title = Heading(_('Add new account'),
                        _('Login with Kano World\n'
                          'or create a new account.'))
        self.attach(title.container, 0, 0, 1, 1)

        # the 2 push buttons
        self.login_btn = KanoButton(_('Kano World'))
        self.login_btn.connect('clicked', self._login_button_pressed)
        self.attach(self.login_btn, 0, 1, 1, 1)

        self.newuser_btn = KanoButton(_('New Account'))
        self.newuser_btn.connect('clicked', self._new_user_reboot)
        self.attach(self.newuser_btn, 0, 2, 1, 1)

    def _login_button_pressed(self, event=None, button=None):
        win = self.get_toplevel()
        win.go_to_login_with_kw()

    def _new_user_reboot(self, event=None, button=None):
        '''
        Schedules kano-init to create a new user from scratch on next reboot,
        then performs the actual reboot
        '''
        confirm = KanoDialog(
            title_text=_('Are you sure you want to create a new account?'),
            description_text=_('A reboot will be required'),
            button_dict=[
                {
                    'label': _('Cancel').upper(),
                    'color': 'red',
                    'return_value': False
                },
                {
                    'label': _('Create').upper(),
                    'color': 'green',
                    'return_value': True
                }
            ])
        confirm.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        if confirm.run():
            os.system("sudo kano-init schedule add-user")
            LightDM.restart()
Exemplo n.º 23
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.º 24
0
    def __init__(self,
                 title,
                 description,
                 buttons,
                 is_plug=False,
                 img_path=None):
        super(Template, self).__init__(orientation=Gtk.Orientation.VERTICAL)
        self._focus_widget = None

        heading = Heading(title, description, is_plug, back_btn=False)
        bbox = Gtk.ButtonBox()
        bbox.set_spacing(20)
        bbox.set_layout(Gtk.ButtonBoxStyle.CENTER)
        bbox.set_margin_right(10)
        bbox.set_margin_left(10)

        for b in buttons:
            label = b["label"]

            if not label:
                gtk_button = Gtk.Label()

            else:
                button_type = b["type"]
                callback = b["callback"]

                if button_type == "KanoButton":
                    color = b["color"]
                    gtk_button = KanoButton(label, color=color)
                elif button_type == "OrangeButton":
                    gtk_button = OrangeButton(label)

                gtk_button.connect("clicked", callback)
            bbox.pack_start(gtk_button, False, False, 0)

            if "focus" in b:
                self._focus_widget = gtk_button

        self.pack_start(heading.container, False, False, 0)
        heading.container.set_margin_right(15)
        heading.container.set_margin_left(15)

        if img_path:
            image = Gtk.Image.new_from_file(img_path)

        if is_plug:
            self.pack_start(image, False, False, 10)
            self.pack_start(bbox, False, False, 30)
        else:
            self.pack_start(image, False, False, 20)
            self.pack_end(bbox, False, False, 30)

        self.show_all()
Exemplo n.º 25
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.º 26
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.º 27
0
class KanoButtonBox(Gtk.Box):
    def __init__(self,
                 kano_button_text,
                 orange_text="",
                 orange_text_2="",
                 orange_text_3=""):

        Gtk.Box.__init__(self)
        self.kano_button = KanoButton(kano_button_text)

        if orange_text != "":
            self.orange_button = OrangeButton(orange_text)
            self.pack_start(self.orange_button, False, False, 0)
            self.pack_start(self.kano_button, False, False, 0)

            if orange_text_2 == "":
                # The empty label is to centre the kano_button
                label = Gtk.Label("    ")
                self.pack_start(label, False, False, 0)
            else:
                self.orange_button2 = OrangeButton(orange_text_2)
                if orange_text_3 == "":
                    self.pack_start(self.orange_button2, False, False, 0)
                else:
                    # If two orange button texts, we align them vertically
                    self.vertbox = Gtk.Box(
                        orientation=Gtk.Orientation.VERTICAL, spacing=6)
                    self.add(self.vertbox)
                    self.orange_button3 = OrangeButton(orange_text_3)
                    self.vertbox.pack_start(self.orange_button2, False, False,
                                            0)
                    self.vertbox.pack_start(self.orange_button3, False, False,
                                            0)
        else:
            self.pack_start(self.kano_button, False, False, 0)

    def get_kano_button(self):
        return self.kano_button

    def set_kano_button_cb(self, cb, args=[]):
        self.kano_button.connect('button-release-event', cb, args)

    def set_orange_button_cb(self, cb, args=[]):
        self.orange_button.connect('button-release-event', cb, args)

    def set_orange_button2_cb(self, cb, args=None):
        self.orange_button2.connect('button-release-event', cb, args)

    def set_orange_button3_cb(self, cb, args=None):
        self.orange_button3.connect('button-release-event', cb, args)
Exemplo n.º 28
0
    def __init__(self):
        Gtk.Window.__init__(self, title=self._TITLE)

        apply_common_to_screen()

        window_height = self._IMAGE_HEIGHT + 220
        self.set_size_request(self._IMAGE_WIDTH, window_height)
        self.set_decorated(False)
        self.set_resizable(False)
        self.set_position(Gtk.WindowPosition.CENTER)

        self.set_icon_name('kano-updater')

        # Put the window above all the existing ones when it starts
        # FIXME: this needs to happen within a 'realized' signal handler
        #        disabled for now
        #self.get_window().raise_()

        image = Gtk.Image()
        image.set_from_file(self._HEADER_IMAGE)

        background = Gtk.EventBox()
        background.set_size_request(self._IMAGE_WIDTH, self._IMAGE_HEIGHT)
        background.add(image)

        # Header
        heading = Heading(self._HEADING, self._BYLINE)
        heading.description.set_line_wrap(True)

        action = KanoButton(self._ACTION.upper())
        action.connect('clicked', self._do_action)
        action.set_halign(Gtk.Align.CENTER)

        later = OrangeButton(_("Later"))
        later.connect('clicked', self._do_later)
        later.set_halign(Gtk.Align.START)
        later.set_margin_left(40)

        buttons = Gtk.Overlay()
        buttons.add(action)
        buttons.add_overlay(later)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        box.pack_start(background, False, False, 0)
        box.pack_start(heading.container, False, False, 10)
        box.pack_start(buttons, False, False, 0)

        self.add(box)

        self.show_all()
Exemplo n.º 29
0
    def __init__(self):
        Gtk.Window.__init__(self, title=self._TITLE)

        apply_common_to_screen()

        window_height = self._IMAGE_HEIGHT + 220
        self.set_size_request(self._IMAGE_WIDTH, window_height)
        self.set_decorated(False)
        self.set_resizable(False)
        self.set_position(Gtk.WindowPosition.CENTER)

        self.set_icon_name('kano-updater')

        # Make sure this window is always above
        self.set_keep_above(True)

        image = Gtk.Image()
        image.set_from_file(self._HEADER_IMAGE)

        background = Gtk.EventBox()
        background.set_size_request(self._IMAGE_WIDTH, self._IMAGE_HEIGHT)
        background.add(image)

        # Header
        heading = Heading(self._HEADING, self._BYLINE)
        heading.description.set_line_wrap(True)

        action = KanoButton(self._ACTION.upper())
        action.connect('clicked', self._do_action)
        action.set_halign(Gtk.Align.CENTER)

        later = OrangeButton(_('Later'))
        later.connect('clicked', Gtk.main_quit)
        later.set_halign(Gtk.Align.START)
        later.set_margin_left(40)

        buttons = Gtk.Overlay()
        buttons.add(action)
        buttons.add_overlay(later)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        box.pack_start(background, False, False, 0)
        box.pack_start(heading.container, False, False, 10)
        box.pack_start(buttons, False, False, 0)

        self.add(box)

        self.show_all()
Exemplo n.º 30
0
class KanoButtonBox(Gtk.Box):

    def __init__(self, kano_button_text, orange_text="", orange_text_2="", orange_text_3=""):

        Gtk.Box.__init__(self)
        self.kano_button = KanoButton(kano_button_text)

        if orange_text != "":
            self.orange_button = OrangeButton(orange_text)
            self.pack_start(self.orange_button, False, False, 0)
            self.pack_start(self.kano_button, False, False, 0)

            if orange_text_2 == "":
                # The empty label is to centre the kano_button
                label = Gtk.Label("    ")
                self.pack_start(label, False, False, 0)
            else:
                self.orange_button2 = OrangeButton(orange_text_2)
                if orange_text_3 == "":
                    self.pack_start(self.orange_button2, False, False, 0)
                else:
                    # If two orange button texts, we align them vertically
                    self.vertbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
                    self.add(self.vertbox)
                    self.orange_button3 = OrangeButton(orange_text_3)
                    self.vertbox.pack_start(self.orange_button2, False, False, 0)
                    self.vertbox.pack_start(self.orange_button3, False, False, 0)
        else:
            self.pack_start(self.kano_button, False, False, 0)

    def get_kano_button(self):
        return self.kano_button

    def set_kano_button_cb(self, cb, args=[]):
        self.kano_button.connect('button-release-event', cb, args)

    def set_orange_button_cb(self, cb, args=[]):
        self.orange_button.connect('button-release-event', cb, args)

    def set_orange_button2_cb(self, cb, args=None):
        self.orange_button2.connect('button-release-event', cb, args)

    def set_orange_button3_cb(self, cb, args=None):
        self.orange_button3.connect('button-release-event', cb, args)
Exemplo n.º 31
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.º 32
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.º 33
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.º 34
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.º 35
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.º 36
0
    def __init__(self, stage, now_cb, later_cb):
        super(ParentalScreen, self).__init__(False, 0)

        self.set_hexpand(False)
        self.set_vexpand(False)
        self.set_margin_left(40)
        self.set_margin_right(40)

        heading = Gtk.Label('For parents...')
        add_class(heading, 'console-screen-heading')

        copy = 'You can put a safety filter on Kano\'s internet. ' + \
               'You can set it now or later.'
        desc = Gtk.Label(copy)
        desc.set_line_wrap(True)
        add_class(desc, 'console-screen-desc')

        padlock = Gtk.Image.new_from_file(stage.media_path('padlock.png'))

        later = KanoButton('GOT IT')
        later.connect('clicked', self._cb_wrapper, later_cb,
                      'init-flow-parental-skipped')
        later.set_size_request(200, 50)

        now = OrangeButton('SET NOW')
        now.connect('clicked', self._cb_wrapper, now_cb,
                    'init-flow-parental-set')

        emptylabel = Gtk.Label("       ")

        buttons = Gtk.ButtonBox()
        buttons.set_layout(Gtk.ButtonBoxStyle.SPREAD)
        buttons.pack_start(emptylabel, True, True, 0)
        buttons.pack_start(later, True, True, 20)
        buttons.pack_start(now, True, True, 20)

        self.pack_start(heading, False, False, 30)
        self.pack_start(desc, False, False, 20)
        self.pack_start(padlock, False, False, 10)
        self.pack_start(buttons, True, True, 30)
Exemplo n.º 37
0
    def __init__(self, stage, scene, yes_cb, no_cb):
        super(ConsoleScreen, self).__init__()

        self.set_size_request(368*scene.scale_factor, 179*scene.scale_factor)
        add_class(self, 'console-screen')

        if scene.scale_factor > 0.8:
            add_class(self, 'font-large')
        else:
            add_class(self, 'font-small')

        vbox = Gtk.VBox(False, 0)
        vbox.set_halign(Gtk.Align.CENTER)
        # vbox.set_valign(Gtk.Align.CENTER)

        question = Gtk.Label('Can you see the lights?')
        question.set_line_wrap(True)
        question.set_justify(Gtk.Justification.CENTER)
        question.set_valign(Gtk.Align.CENTER)
        add_class(question, 'console-screen-question')

        vbox.pack_start(question, True, False, 0)

        hbox = Gtk.HBox(False, 20)
        hbox.set_halign(Gtk.Align.CENTER)
        hbox.set_valign(Gtk.Align.CENTER)

        yes = KanoButton('YES')
        yes.connect('clicked', cb_wrapper, yes_cb)

        no = KanoButton('NO', color='red')
        no.connect('clicked', cb_wrapper, no_cb)

        hbox.pack_start(yes, False, False, 0)
        hbox.pack_start(no, False, False, 0)

        vbox.pack_start(hbox, True, False, 0)
        self.add(vbox)
Exemplo n.º 38
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.º 39
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.º 40
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.º 41
0
class PasswordView(Gtk.Grid):
    def __init__(self, user, greeter):
        Gtk.Grid.__init__(self)

        self.get_style_context().add_class('password')
        self.set_row_spacing(10)

        self.greeter = greeter

        self.user = user
        self.title = self._set_title()

        self.attach(self.title.container, 0, 0, 1, 1)
        self.label = Gtk.Label(user)
        self.label.get_style_context().add_class('login')
        self.attach(self.label, 0, 1, 1, 1)
        self.password = Gtk.Entry()
        self.password.set_visibility(False)
        self.password.set_alignment(0.5)
        self.password.connect('activate', self._login_cb)
        self.attach(self.password, 0, 2, 1, 1)

        self.login_btn = KanoButton(_('Login').upper())
        self.login_btn.connect('clicked', self._login_cb)
        self.attach(self.login_btn, 0, 3, 1, 1)

        # Protect against removing the last Kano user
        # so you do not get locked out from logging into the Kit
        system_users = KanoUserList().get_users()
        if len(system_users) > 1:
            delete_account_btn = OrangeButton(_('Remove Account'))
            delete_account_btn.connect('clicked', self.delete_user)
            self.attach(delete_account_btn, 0, 4, 1, 1)

    def _set_title(self, create=True):
        '''
        Creates a Heading text widget, or updates it
        with the currently selected username.
        '''
        text_title = _('{}: Enter your password').format(self.user)
        text_description = _(
            'If you haven\'t changed your\npassword, use "kano"')

        if create:
            title = Heading(text_title, text_description)
            return title
        else:
            self.title.set_text(text_title, text_description)
            return self.title

    def _reset_greeter(self):
        # connect signal handlers to LightDM
        self.cb_one = self.greeter.connect('show-prompt',
                                           self._send_password_cb)
        self.cb_two = self.greeter.connect('authentication-complete',
                                           self._authentication_complete_cb)
        self.cb_three = self.greeter.connect('show-message',
                                             self._auth_error_cb)

        self.greeter.connect_sync()
        return (self.cb_one, self.cb_two, self.cb_three)

    def _login_cb(self, event=None, button=None):
        logger.debug('Sending username to LightDM')

        self.login_btn.start_spinner()
        Gtk.main_iteration_do(True)

        self.greeter.authenticate(self.user)

        if self.greeter.get_is_authenticated():
            logger.debug('User is already authenticated, starting session')
            start_session()

    def _send_password_cb(self, _greeter, text, prompt_type):
        logger.debug('Need to show prompt: {}'.format(text))

        if _greeter.get_in_authentication():
            logger.debug('Sending password to LightDM')
            _greeter.respond(self.password.get_text())

    def _authentication_complete_cb(self, _greeter):
        logger.debug('Authentication process is complete')

        if not _greeter.get_is_authenticated():
            logger.warn('Could not authenticate user {}'.format(self.user))
            self._auth_error_cb(
                _('Incorrect password (The default is "kano")'))

            return

        logger.info(
            'The user {} is authenticated. Starting LightDM X Session'.format(
                self.user))

        set_last_user(self.user)

        if not _greeter.start_session_sync('lightdm-xsession'):
            logger.error('Failed to start session')
        else:
            logger.info('Login failed')

    def _auth_error_cb(self, text, message_type=None):
        logger.info('There was an error logging in: {}'.format(text))

        self.greeter.cancel_authentication()

        self.login_btn.stop_spinner()
        self.password.set_text('')

        win = self.get_toplevel()
        error = KanoDialog(title_text=_('Error Logging In'),
                           description_text=text,
                           parent_window=win)
        error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        error.run()
        win.go_to_users()

    def grab_focus(self, user):
        '''
        Update username title, clear previous password,
        and give focus to password entry field.
        '''
        self.user = user
        self._set_title(create=False)

        self.password.set_text('')
        self.password.grab_focus()

    def delete_user(self, *args):
        import pam

        password_input = Gtk.Entry()
        password_input.set_visibility(False)
        password_input.set_alignment(0.5)

        confirm = KanoDialog(
            title_text=_('Are you sure you want to delete this account?'),
            description_text=_(
                'Enter {}\'s password - A reboot will be required'.format(
                    self.user)),
            widget=password_input,
            has_entry=True,
            button_dict=[{
                'label': _('Cancel').upper(),
                'color': 'red',
                'return_value': False
            }, {
                'label': _('Ok').upper(),
                'color': 'green',
                'return_value': True
            }])

        confirm.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        # Kano Dialog will return False if cancel button is clicked, or text from the entry field if Ok
        response = confirm.run()
        if response == False:
            return
        elif type(response) == str and not len(response):
            error = KanoDialog(title_text=_(
                'Please enter the password for user {}'.format(self.user)))
            error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
            error.run()
            return
        else:
            password = response

        # Authenticate user and schedule removal. Protect against unknown troubles.
        try:
            if pam.authenticate(self.user, password):
                info = KanoDialog(title_text = _('User {} scheduled for removal'.format(self.user)), \
                                  description_text = _('Press OK to reboot'))
                info.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
                info.run()

                os.system('sudo kano-init schedule delete-user "{}"'.format(
                    self.user))
                LightDM.restart()
            else:
                error = KanoDialog(title_text=_(
                    'Incorrect password for user {}'.format(self.user)))
                error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
                error.run()
        except Exception as e:
            logger.error('Error deleting account {} - {}'.format(
                self.user, str(e)))
            error = KanoDialog(
                title_text=_('Could not delete account {}'.format(self.user)))
            error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
            error.run()
Exemplo n.º 42
0
class EditableList(Gtk.Grid):
    def __init__(self, size_x=400, size_y=150):
        Gtk.Grid.__init__(self)

        self.set_row_spacing(10)
        self.set_column_spacing(10)

        scroll = ScrolledWindow()
        scroll.set_size_request(size_x, size_y)
        scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self.edit_list_store = Gtk.ListStore(str)
        self.edit_list = Gtk.TreeView(self.edit_list_store)
        self.edit_list.set_headers_visible(False)

        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', True)
        renderer.connect('edited', self._item_edited_handler)
        renderer.connect('editing-started', self._item_edit_started)
        renderer.connect('editing-canceled', self._item_edit_canceled)
        column = Gtk.TreeViewColumn(cell_renderer=renderer, text=0)
        self.edit_list.append_column(column)

        self._add_btn = KanoButton(_("ADD"))
        self._add_btn.connect('button-release-event', self.add)
        self._rm_btn = KanoButton(_("REMOVE"))
        self._set_rm_btn_state()
        self._rm_btn.connect('button-release-event', self.rm)

        scroll.add_with_viewport(self.edit_list)

        self.attach(scroll, 0, 0, 2, 1)
        self.attach(self._add_btn, 0, 1, 1, 1)
        self.attach(self._rm_btn, 1, 1, 1, 1)

    def __contains__(self, item):
        return item in [row[0] for row in self.edit_list_store]

    def add(self, button, event):
        self.edit_list_store.append([''])

        self.edit_list.grab_focus()

        row = len(self.edit_list_store) - 1
        col = self.edit_list.get_column(0)
        self.edit_list.set_cursor(row, col, start_editing=True)
        self._rm_btn.set_sensitive(False)

    def rm(self, button=None, event=None):
        selection = self.edit_list.get_selection()
        dummy, selected = selection.get_selected()

        if not selected:
            return

        self.edit_list_store.remove(selected)
        self._set_rm_btn_state()

    def _item_edited_handler(self, cellrenderertext, path, new_text):
        if new_text is None:
            # FIXME: the reason for the os.system here is that the 'edited' signal
            # triggers on a key-pressed-event and the dialog closes on release. So
            # you would only see the dialog while holding down the 'ENTER' key.
            title = _("Invalid website given")
            description = _("\nWe need to make sure the website URL is valid.\n" \
                            "Please enter the full URL as it appears in your browser.\n\n" \
                            "Example: http://www.google.com\n")
            buttons = _("OK:red:1")
            cmd = 'kano-dialog title="{}" description="{}" buttons="{}" no-taskbar &'.format(
                title.encode('utf8'), description.encode('utf8'),
                buttons.encode('utf8'))
            os.system(cmd)
            self.rm()

        else:
            selection = self.edit_list.get_selection()
            dummy, selected = selection.get_selected()

            if new_text and new_text not in self:
                self.edit_list_store.set_value(selected, 0, new_text)
            else:
                row = self.edit_list_store[selected]
                old_text = row[0]

                if not old_text:
                    self.rm()

        self._add_btn.set_sensitive(True)
        self._set_rm_btn_state()

    def _item_edit_started(self, *_):
        self._add_btn.set_sensitive(False)

    def _item_edit_canceled(self, *_):
        self._add_btn.set_sensitive(True)
        self.rm()

    def _set_rm_btn_state(self):
        state = len(self.edit_list_store) != 0

        self._rm_btn.set_sensitive(state)
Exemplo n.º 43
0
class PasswordView(Gtk.Grid):

    def __init__(self, user, greeter):
        Gtk.Grid.__init__(self)

        self.get_style_context().add_class('password')
        self.set_row_spacing(10)

        self.greeter = greeter

        self.user = user
        self.title = self._set_title()

        self.attach(self.title.container, 0, 0, 1, 1)
        self.label = Gtk.Label(user)
        self.label.get_style_context().add_class('login')
        self.attach(self.label, 0, 1, 1, 1)
        self.password = Gtk.Entry()
        self.password.set_visibility(False)
        self.password.set_alignment(0.5)
        self.password.connect('activate', self._login_cb)
        self.attach(self.password, 0, 2, 1, 1)

        self.login_btn = KanoButton(_('Login').upper())
        self.login_btn.connect('clicked', self._login_cb)
        self.attach(self.login_btn, 0, 3, 1, 1)

        # Protect against removing the last Kano user
        # so you do not get locked out from logging into the Kit
        system_users = KanoUserList().get_users()
        if len(system_users) > 1:
            delete_account_btn = OrangeButton(_('Remove Account'))
            delete_account_btn.connect('clicked', self.delete_user)
            self.attach(delete_account_btn, 0, 4, 1, 1)

    def _set_title(self, create=True):
        '''
        Creates a Heading text widget, or updates it
        with the currently selected username.
        '''
        text_title = _('{}: Enter your password').format(self.user)
        text_description = _('If you haven\'t changed your\npassword, use "kano"')

        if create:
            title = Heading(text_title, text_description)
            return title
        else:
            self.title.set_text(text_title, text_description)
            return self.title

    def _reset_greeter(self):
        # connect signal handlers to LightDM
        self.cb_one = self.greeter.connect('show-prompt', self._send_password_cb)
        self.cb_two = self.greeter.connect('authentication-complete',
                                           self._authentication_complete_cb)
        self.cb_three = self.greeter.connect('show-message', self._auth_error_cb)

        self.greeter.connect_sync()
        return (self.cb_one, self.cb_two, self.cb_three)

    def _login_cb(self, event=None, button=None):
        logger.debug('Sending username to LightDM')

        self.login_btn.start_spinner()
        Gtk.main_iteration_do(True)

        # The call below will simply initiate the login flow.
        # The greeter library will inform us through callbacks
        # See: http://web.mit.edu/Source/debathena/config/lightdm-config/debian/debathena-lightdm-greeter
        self.greeter.authenticate(self.user)

    def _send_password_cb(self, _greeter, text, prompt_type):
        logger.debug(u'Need to show prompt: {}'.format(text))

        if _greeter.get_in_authentication():
            logger.debug('Sending password to LightDM')
            _greeter.respond(self.password.get_text())

    def _authentication_complete_cb(self, _greeter):
        logger.debug('Authentication process is complete')

        if not _greeter.get_is_authenticated():
            logger.warn('Could not authenticate user {}'.format(self.user))
            self._auth_error_cb(_('Incorrect password (The default is "kano")'))
            return

        logger.info(
            'The user {} is authenticated. Starting LightDM X Session'
            .format(self.user))

        set_last_user(self.user)

        if not _greeter.start_session_sync('lightdm-xsession'):
            logger.error('Failed to start session')
        else:
            logger.info('Login failed')

    def _auth_error_cb(self, text, message_type=None):
        logger.info(u'There was an error logging in: {}'.format(text))

        self.greeter.cancel_authentication()

        self.login_btn.stop_spinner()
        self.password.set_text('')

        win = self.get_toplevel()
        error = KanoDialog(
            title_text=_('Error Logging In'),
            description_text=text,
            parent_window=win
        )
        error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        error.run()
        win.go_to_users()

    def grab_focus(self, user):
        '''
        Update username title, clear previous password,
        and give focus to password entry field.
        '''
        self.user = user
        self._set_title(create=False)

        self.password.set_text('')
        self.password.grab_focus()

    def delete_user(self, *args):
        import pam

        password_input = Gtk.Entry()
        password_input.set_visibility(False)
        password_input.set_alignment(0.5)

        confirm = KanoDialog(
            title_text = _('Are you sure you want to delete this account?'),
            description_text = _('Enter {}\'s password - A reboot will be required'.format(self.user)),
            widget=password_input,
            has_entry=True,
            button_dict = [
                {
                    'label': _('Cancel').upper(),
                    'color': 'red',
                    'return_value': False
                },
                {
                    'label': _('Ok').upper(),
                    'color': 'green',
                    'return_value': True
                }
            ])

        confirm.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        # Kano Dialog will return False if cancel button is clicked, or text
        # from the entry field if Ok
        response = confirm.run()
        if not response:
            return
        elif type(response) == str and not len(response):
            error = KanoDialog(
                title_text=_('Please enter the password for user {}'.format(self.user))
            )
            error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
            error.run()
            return
        else:
            password = response

        # Authenticate user and schedule removal. Protect against unknown troubles.
        try:
            if pam.authenticate(self.user, password):
                info = KanoDialog(
                    title_text=_('User {} scheduled for removal'.format(self.user)),
                    description_text=_('Press OK to reboot')
                )
                info.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
                info.run()

                os.system('sudo kano-init schedule delete-user "{}"'.format(self.user))
                LightDM.restart()
            else:
                error = KanoDialog(
                    title_text=_('Incorrect password for user {}'.format(self.user))
                )
                error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
                error.run()
        except Exception as e:
            logger.error(u'Error deleting account {} - {}'.format(self.user, str(e)))
            error = KanoDialog(
                title_text=_('Could not delete account {}'.format(self.user))
            )
            error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
            error.run()
Exemplo n.º 44
0
class RegistrationScreen(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.set_decorated(True)

        title = Heading(_("Kano World"),
                        _("Choose a cool name and secure password"))
        self.pack_start(title.container, False, False, 0)

        self.data_screen = GetData()  # TODO: refactor this
        self.data_screen.connect('widgets-filled',
                                 self._enable_register_button)
        self.data_screen.connect('widgets-empty',
                                 self._disable_register_button)
        self.add(self.data_screen)

        self.register_button = KanoButton(_("JOIN KANO WORLD"))
        self.register_button.set_sensitive(False)
        self.register_button.set_margin_top(10)
        self.register_button.set_margin_left(30)
        self.register_button.set_margin_right(30)
        self.register_button.set_margin_bottom(30)
        self.register_button.connect('clicked', self._on_register_button)
        self.pack_end(self.register_button, False, False, 0)

        self.win.show_all()

    def _enable_register_button(self, widget=None):
        """
        """
        self.register_button.set_sensitive(True)

    def _disable_register_button(self, widget=None):
        """
        """
        self.register_button.set_sensitive(False)

    def _on_register_button(self, widget=None):  # TODO: refactor this
        """
        """
        if not is_internet():
            self._show_not_internet_dialog()
            return

        # Get the username, password and birthday
        data = self.data_screen.get_widget_data()
        email = data['email']
        username = data['username']

        # Validate that the email address format is correct
        email_error = validate_email(email)
        if email_error:
            self._show_error_dialog(_("Incorrect Email address"), email_error)
            return

        if not self._is_username_available(username):
            self._show_username_taken_dialog(username)
            return

        # We can save the username to kano-profile
        # Don't save password as this is private
        self.data_screen.save_username_and_birthday()  # TODO: rename this
        self.data_screen.cache_emails()
        data = self.data_screen.get_widget_data()

        # This means no threads are needed.
        while Gtk.events_pending():  # TODO: why is this needed?
            Gtk.main_iteration()

        # Try and register the account on the server
        password = data['password']
        success, text = register_(email,
                                  username,
                                  password,
                                  marketing_enabled=True)

        # This should no longer be needed, since this is checked in the first
        # screen. However there is a small chance someone could take the
        # username while the user is in the process of registering
        if not success:
            if text.strip() == _("Cannot register, problem: "
                                 "Username already registered"):

                self._show_username_taken_dialog(username)

            else:
                logger.info("problem with registration: {}".format(text))
                return_value = 'FAIL'
                self._create_dialog(title=_("Houston, we have a problem"),
                                    description=str(text))
                track_data('world-registration-failed', {'reason': text})

        else:
            logger.info("registration successful")

            # saving hardware info and initial Kano version
            save_hardware_info()
            save_kano_version()

            # running kano-sync after registration
            logger.info("running kano-sync after successful registration")
            cmd = '{bin_dir}/kano-sync --sync -s'.format(bin_dir=bin_dir)
            run_bg(cmd)

            return_value = 'SUCCEED'
            self._create_dialog(
                title=_("Profile activated!"),
                description=_("Now you can share stuff, build your character, "
                              "and connect with friends."))

        self.win.get_window().set_cursor(None)

        # Close the app if it was successful
        if return_value == 'SUCCEED':
            Gtk.main_quit()

    def _is_username_available(self, name):
        """
        Returns True if username is available, and False otherwise
        """
        # Use the endpoint api.kano.me/users/username/:name
        success, text, data = request_wrapper(
            'get',
            '/users/username/{}'.format(name),
            headers=content_type_json)

        if not success and text.strip() == "User not found":
            return True
        elif success:
            # Username is definitely taken
            return False
        else:
            # Maybe let the user know something went wrong? e.g. if there's no
            # internet, launch a dialog at this point
            return False

    def _create_dialog(self, title, description):  # TODO: refactor this
        kdialog = KanoDialog(title, description, parent_window=self.win)
        rv = kdialog.run()
        return rv

    def _show_error_dialog(self, title, description):  # TODO: refactor this
        kdialog = KanoDialog(title, description, parent_window=self.win)
        kdialog.run()

    def _show_username_taken_dialog(self, username):  # TODO: refactor this
        track_data('world-registration-username-taken', {'username': username})
        kd = KanoDialog(_("This username is taken!"),
                        _("Try another one"),
                        parent_window=self.win)
        kd.run()
        self.data_screen.username.set_text("")
        self.data_screen.validate_username()
        self._disable_register_button()
        self.data_screen.username.grab_focus()

    def _show_not_internet_dialog(self):  # TODO: refactor this
        kd = KanoDialog(_("You don't have internet"),
                        _("Do you want to connect to WiFi?"),
                        [{
                            'label': _("YES"),
                            'color': 'green',
                            'return_value': 0
                        }, {
                            'label': _("NO"),
                            'color': 'red',
                            'return_value': 1
                        }],
                        parent_window=self.win)
        response = kd.run()

        # Close the dialog
        while Gtk.events_pending():  # TODO: why is this needed?
            Gtk.main_iteration()

        if response == 0:
            subprocess.Popen("sudo kano-wifi-gui", shell=True)
Exemplo n.º 45
0
class SetProxy(Gtk.Box):
    def __init__(self, win):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
        self.kano_button = KanoButton()

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

        self.heading = Heading(
            _("Proxy"),
            _("Connect via a friend")
        )

        grid = Gtk.Grid(column_homogeneous=False, column_spacing=10, row_spacing=10)

        self.kano_button.connect('button-release-event', self.apply_changes)
        self.kano_button.connect('key-release-event', self.apply_changes)
        self.win.top_bar.enable_prev()
        self.win.change_prev_callback(self.go_to_wifi)

        self.ip_entry = Gtk.Entry()
        self.ip_entry.props.placeholder_text = _("IP address")
        self.ip_entry.connect('key-release-event', self.proxy_enabled)

        self.username_entry = Gtk.Entry()
        self.username_entry.props.placeholder_text = _("Username")
        self.username_entry.connect('key-release-event', self.proxy_enabled)

        self.port_entry = Gtk.Entry()
        self.port_entry.props.placeholder_text = _("Port")
        self.port_entry.connect('key-release-event', self.proxy_enabled)

        self.password_entry = Gtk.Entry()
        self.password_entry.props.placeholder_text = _("Password")
        self.password_entry.set_visibility(False)
        self.password_entry.connect('key-release-event', self.proxy_enabled)

        password_box = Gtk.Box()
        password_box.add(self.password_entry)

        self.checkbutton = Gtk.CheckButton(_("enable proxy"))
        self.read_config()
        self.checkbutton.connect('clicked', self.proxy_status)
        self.checkbutton.set_can_focus(False)

        bottom_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        bottom_row.pack_start(self.checkbutton, False, False, 0)
        bottom_row.pack_start(self.kano_button, False, False, 60)
        bottom_row.set_margin_bottom(30)
        bottom_row.set_margin_left(70)

        grid.attach(self.ip_entry, 0, 0, 2, 2)
        grid.attach(self.username_entry, 0, 2, 2, 2)
        grid.attach(self.port_entry, 2, 0, 2, 2)
        grid.attach(password_box, 2, 2, 3, 2)

        grid_alignment = Gtk.Alignment(xscale=0, xalign=0.5, yscale=0, yalign=0.2)
        grid_alignment.add(grid)

        self.pack_start(self.heading.container, False, False, 0)
        self.pack_start(grid_alignment, True, True, 0)
        self.pack_end(bottom_row, False, False, 0)

        self.proxy_status(self.checkbutton)
        self.kano_button.set_sensitive(False)

        # Change text of kano button depending on if proxy is enabled
        if self.checkbutton.get_active():
            self.kano_button.set_label(_("ENABLE PROXY"))
        else:
            self.kano_button.set_label(_("DISABLE PROXY"))

        self.win.show_all()

    def clear_entries(self):
        self.ip_entry.set_text("")
        self.username_entry.set_text("")
        self.port_entry.set_text("")
        self.password_entry.set_text("")

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

    # Update for proxy
    def read_config(self):
        self.enable_proxy, data, _ = get_all_proxies()
        self.enabled_init = self.enable_proxy
        if self.enable_proxy:
            try:
                self.ip_entry.set_text(data['host'])
                self.port_entry.set_text(data['port'])
                if data['username']:
                    self.username_entry.set_text(data['username'])
                if data['password']:
                    self.password_entry.set_text(data['password'])
            except:
                # Something went wrong > disable proxy
                set_all_proxies(False)
                common.proxy_enabled = False
                self.enable_proxy = False
                self.enabled_init = False
                self.clear_entries()
        self.checkbutton.set_active(self.enable_proxy)

    def apply_changes(self, button, event):
        # If enter key is pressed or mouse button is clicked
        if not hasattr(event, 'keyval') or event.keyval == 65293:

            # This is a callback called by the main loop, so it's safe to
            # manipulate GTK objects:
            watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
            self.win.get_window().set_cursor(watch_cursor)
            self.kano_button.start_spinner()
            self.kano_button.set_sensitive(False)

            def lengthy_process():

                if self.enable_proxy:
                    host = self.ip_entry.get_text()
                    port = self.port_entry.get_text()
                    username = self.username_entry.get_text()
                    password = self.password_entry.get_text()
                    set_all_proxies(enable=True, host=host, port=port, username=username, password=password)
                    common.proxy_enabled = True

                    success, text = test_proxy()
                    if not success:
                        title = _("Error with proxy")
                        description = text
                        return_value = 1

                        # disable proxy if we couldn't successfully enable it
                        set_all_proxies(False)
                        common.proxy_enabled = False
                    else:
                        title = _("Successfully enabled proxy")
                        description = ""
                        return_value = 0

                else:
                    set_all_proxies(False)
                    common.proxy_enabled = False
                    title = _("Successfully disabled proxy")
                    description = ""
                    return_value = 0

                def done(title, description, return_value):
                    kdialog = KanoDialog(
                        title,
                        description,
                        [
                            {
                                'label': _("OK"),
                                'color': 'green',
                                'return_value': return_value
                            }
                        ],
                        parent_window=self.win
                    )
                    response = kdialog.run()
                    self.win.get_window().set_cursor(None)
                    self.kano_button.stop_spinner()

                    if response == 0:
                        self.go_to_wifi()
                    elif response == 1:
                        self.checkbutton.set_active(False)
                        self.kano_button.set_sensitive(False)

                GObject.idle_add(done, title, description, return_value)

            thread = threading.Thread(target=lengthy_process)
            thread.start()

    # Validation functions
    # If the "enable proxy" checkbox is checked/uncheckout, this function is activated
    # Disables the text entries if enable proxy is not checked
    def proxy_status(self, widget):
        self.enable_proxy = widget.get_active()
        if self.enable_proxy:
            self.ip_entry.set_sensitive(True)
            self.port_entry.set_sensitive(True)
            self.password_entry.set_sensitive(True)
            self.username_entry.set_sensitive(True)
            # Run to see if it need enabling
            self.proxy_enabled()
            self.kano_button.set_label(_("ENABLE PROXY"))

        else:
            self.ip_entry.set_sensitive(False)
            self.port_entry.set_sensitive(False)
            self.password_entry.set_sensitive(False)
            self.username_entry.set_sensitive(False)
            self.kano_button.set_label(_("DISABLE PROXY"))
            self.kano_button.set_sensitive(True)

    # if proxy enabled: ip address, port are mandatory
    def proxy_enabled(self, widget=None, event=None):
        # Get IP address
        # Get port
        # Get
        # If these entries are non empty, good - else, disable the next button
        ip_text = self.ip_entry.get_text()
        port_text = self.port_entry.get_text()

        if ip_text == "" or port_text == "":
            self.kano_button.set_sensitive(False)
            return False

        else:
            self.kano_button.set_sensitive(True)
            return True

        return False
Exemplo n.º 46
0
class LoginWithKanoWorldView(Gtk.Grid):

    def __init__(self, greeter):
        Gtk.Grid.__init__(self)

        self.get_style_context().add_class('password')
        self.set_row_spacing(12)

        self.greeter = greeter

        title = Heading(_('Login with Kano World'),
                        _('Enter your Kano World details.'))
        self.attach(title.container, 0, 0, 1, 1)

        self.username = Gtk.Entry()
        self.username.set_placeholder_text('username')
        self.attach(self.username, 0, 1, 1, 1)

        self.password = Gtk.Entry()
        self.password.set_visibility(False)
        self.password.set_placeholder_text('password')
        self.attach(self.password, 0, 2, 1, 1)

        self.login_btn = KanoButton(_('LOGIN'))
        self.login_btn.connect('clicked', self._btn_login_pressed)
        self.attach(self.login_btn, 0, 3, 1, 1)

    def _btn_login_pressed(self, event=None, button=None):
        '''
        Authenticates against Kano World. If successful synchronizes to a local
        Unix account, and tells lightdm to go forward with local a login.
        '''
        logger.debug('Synchronizing Kano World account')
        self.login_btn.start_spinner()
        self.login_btn.set_sensitive(False)

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

    def _thr_login(self):
        loggedin = False
        reason = ''

        # TODO: Disable the "login" button unless these entry fields are non-empty
        # Collect credentials from the view
        self.unix_password = self.password.get_text()
        self.world_username = self.username.get_text()
        self.unix_username = self.username.get_text()
        atsign = self.unix_username.find('@')
        if atsign != -1:
            # For if we are in "staging" mode (see /etc/kano-world.conf)
            self.unix_username = self.unix_username[:atsign]

        # Now try to login to Kano World
        try:
            logger.debug('Authenticating user: {} to Kano World'.format(self.username.get_text()))
            (loggedin, reason) = kano_world_authenticate(self.username.get_text(), self.password.get_text())
            logger.debug('Kano World auth response: {} - {}'.format(loggedin, reason))
        except Exception as e:
            reason = str(e)
            logger.debug('Kano World auth Exception: {}'.format(reason))
            pass

        if not loggedin:
            # Kano world auth unauthorized
            # FIXME: Localizing the below string fails with an exception
            GObject.idle_add(self._error_message_box, 'Failed to authenticate to Kano World', reason)
            return
        else:
            # We are authenticated to Kano World: proceed with forcing local user
            rc = -1
            try:
                # Create the local unix user, bypass kano-init-flow, login & sync to Kano World
                createuser_cmd = 'sudo /usr/bin/kano-greeter-account {} {} {}'.format(
                    self.unix_username, self.unix_password, self.world_username)
                _, _, rc = run_cmd(createuser_cmd)
                if rc == 0:
                    logger.debug('Local user created correctly: {}'.format(self.unix_username))
                elif rc == 1:
                    logger.debug('Local user already exists, proceeding with login: {}'.format(self.unix_username))

                created = True
            except:
                created = False

            if not created:
                logger.debug('Error creating new local user: {}'.format(self.unix_username))
                GObject.idle_add(self._error_message_box, "Could not create local user", rc)
                return

            # Tell Lidghtdm to proceed with login session using the new user
            # We bind LightDM at this point only, this minimizes the number of attempts
            # to bind the Greeter class to a view, which he does not like quite well.
            logger.debug('Scheduling lightdm authentication in math thread')
            GObject.idle_add(self._auth_call)

    def _auth_call(self):
        logger.debug('Starting lightdm authentication')
        self._reset_greeter()
        self.greeter.authenticate(self.unix_username)
        if self.greeter.get_is_authenticated():
            logger.debug('User is already authenticated, starting session')

    def _reset_greeter(self):
        # connect signal handlers to LightDM
        self.cb_one = self.greeter.connect('show-prompt', self._send_password_cb)
        self.cb_two = self.greeter.connect('authentication-complete',
                                           self._authentication_complete_cb)
        self.cb_three = self.greeter.connect('show-message', self._auth_error_cb)
        self.greeter.connect_sync()
        return (self.cb_one, self.cb_two, self.cb_three)

    def _send_password_cb(self, _greeter, text, prompt_type):
        logger.debug('Need to show prompt: {}'.format(text))
        if _greeter.get_in_authentication():
            logger.debug('Sending password to LightDM')
            _greeter.respond(self.unix_password)

    def _authentication_complete_cb(self, _greeter):
        logger.debug('Authentication process is complete')

        if not _greeter.get_is_authenticated():
            logger.warn('Could not authenticate user {}'.format(self.unix_username))
            self._auth_error_cb(_('Incorrect password (The default is "kano")'))
            return

        logger.info(
            'The user {} is authenticated. Starting LightDM X Session'
            .format(self.unix_username))

        set_last_user(self.unix_username)

        if not _greeter.start_session_sync('lightdm-xsession'):
            logger.error('Failed to start session')
        else:
            logger.info('Login failed')

    def _auth_error_cb(self, text, message_type=None):
        logger.info('There was an error logging in: {}'.format(text))

        win = self.get_toplevel()
        win.go_to_users()

        self.login_btn.stop_spinner()
        self.login_btn.set_sensitive(True)
        self.newuser_btn.set_sensitive(True)

        error = KanoDialog(title_text=_('Error Synchronizing account'),
                           description_text=text,
                           parent_window=self.get_toplevel())
        error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        error.run()

    def _error_message_box(self, title, description):
        '''
        Show a standard error message box
        '''
        self.login_btn.stop_spinner()
        self.login_btn.set_sensitive(True)

        errormsg = KanoDialog(title_text=title,
                              description_text=description,
                              button_dict=[
                                  {
                                      'label': _('OK').upper(),
                                      'color': 'red',
                                      'return_value': True
                                  }])

        errormsg.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        errormsg.run()

        # Clean up password field
        self.password.set_text('')
        return

    def grab_focus(self):
        '''
        Clear username and password previous text, and gain focus.
        '''
        self.username.set_text('')
        self.password.set_text('')
Exemplo n.º 47
0
class EditableList(Gtk.Grid):

    def __init__(self, size_x=400, size_y=150):
        Gtk.Grid.__init__(self)

        self.set_row_spacing(10)
        self.set_column_spacing(10)

        scroll = ScrolledWindow()
        scroll.set_size_request(size_x, size_y)
        scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self.edit_list_store = Gtk.ListStore(str)
        self.edit_list = Gtk.TreeView(self.edit_list_store)
        self.edit_list.set_headers_visible(False)

        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', True)
        renderer.connect('edited', self._item_edited_handler)
        renderer.connect('editing-started', self._item_edit_started)
        renderer.connect('editing-canceled', self._item_edit_canceled)
        column = Gtk.TreeViewColumn(cell_renderer=renderer, text=0)
        self.edit_list.append_column(column)

        self._add_btn = KanoButton(_("ADD"))
        self._add_btn.connect('button-release-event', self.add)
        self._rm_btn = KanoButton(_("REMOVE"))
        self._set_rm_btn_state()
        self._rm_btn.connect('button-release-event', self.rm)

        scroll.add_with_viewport(self.edit_list)

        self.attach(scroll, 0, 0, 2, 1)
        self.attach(self._add_btn, 0, 1, 1, 1)
        self.attach(self._rm_btn, 1, 1, 1, 1)

    def __contains__(self, item):
        return item in [row[0] for row in self.edit_list_store]

    def add(self, button, event):
        self.edit_list_store.append([''])

        self.edit_list.grab_focus()

        row = len(self.edit_list_store) - 1
        col = self.edit_list.get_column(0)
        self.edit_list.set_cursor(row, col, start_editing=True)
        self._rm_btn.set_sensitive(False)

    def rm(self, button=None, event=None):
        selection = self.edit_list.get_selection()
        dummy, selected = selection.get_selected()

        if not selected:
            return

        self.edit_list_store.remove(selected)
        self._set_rm_btn_state()

    def _item_edited_handler(self, cellrenderertext, path, new_text):
        if new_text is None:
            # FIXME: the reason for the os.system here is that the 'edited' signal
            # triggers on a key-pressed-event and the dialog closes on release. So
            # you would only see the dialog while holding down the 'ENTER' key.
            title = _("Invalid website given")
            description = _("\nWe need to make sure the website URL is valid.\n" \
                            "Please enter the full URL as it appears in your browser.\n\n" \
                            "Example: http://www.google.com\n")
            buttons = _("OK:red:1")
            cmd = 'kano-dialog title="{}" description="{}" buttons="{}" no-taskbar &'.format(
                  title.encode('utf8'), description.encode('utf8'), buttons.encode('utf8'))
            os.system(cmd)
            self.rm()

        else:
            selection = self.edit_list.get_selection()
            dummy, selected = selection.get_selected()

            if new_text and new_text not in self:
                self.edit_list_store.set_value(selected, 0, new_text)
            else:
                row = self.edit_list_store[selected]
                old_text = row[0]

                if not old_text:
                    self.rm()

        self._add_btn.set_sensitive(True)
        self._set_rm_btn_state()

    def _item_edit_started(self, *_):
        self._add_btn.set_sensitive(False)

    def _item_edit_canceled(self, *_):
        self._add_btn.set_sensitive(True)
        self.rm()

    def _set_rm_btn_state(self):
        state = len(self.edit_list_store) != 0

        self._rm_btn.set_sensitive(state)
Exemplo n.º 48
0
class LoginWithKanoWorldView(Gtk.Grid):
    def __init__(self, greeter):
        Gtk.Grid.__init__(self)

        self.get_style_context().add_class('password')
        self.set_row_spacing(12)

        self.greeter = greeter

        title = Heading(_('Login with Kano World'),
                        _('Enter your Kano World details.'))
        self.attach(title.container, 0, 0, 1, 1)

        self.username = Gtk.Entry()
        self.username.set_placeholder_text('username')
        self.attach(self.username, 0, 1, 1, 1)

        self.password = Gtk.Entry()
        self.password.set_visibility(False)
        self.password.set_placeholder_text('password')
        self.attach(self.password, 0, 2, 1, 1)

        self.login_btn = KanoButton(_('LOGIN'))
        self.login_btn.connect('clicked', self._btn_login_pressed)
        self.attach(self.login_btn, 0, 3, 1, 1)

    def _btn_login_pressed(self, event=None, button=None):
        '''
        Authenticates against Kano World. If successful synchronizes to a local
        Unix account, and tells lightdm to go forward with local a login.
        '''
        logger.debug('Synchronizing Kano World account')
        self.login_btn.start_spinner()
        self.login_btn.set_sensitive(False)

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

    def _thr_login(self):
        loggedin = False
        reason = ''

        # TODO: Disable the "login" button unless these entry fields are non-empty
        # Collect credentials from the view
        self.unix_password = self.password.get_text()
        self.world_username = self.username.get_text()
        self.unix_username = self.username.get_text()
        atsign = self.unix_username.find('@')
        if atsign != -1:
            # For if we are in "staging" mode (see /etc/kano-world.conf)
            self.unix_username = self.unix_username[:atsign]

        # Now try to login to Kano World
        try:
            logger.debug('Authenticating user: {} to Kano World'.format(
                self.username.get_text()))
            (loggedin,
             reason) = kano_world_authenticate(self.username.get_text(),
                                               self.password.get_text())
            logger.debug('Kano World auth response: {} - {}'.format(
                loggedin, reason))
        except Exception as e:
            reason = str(e)
            logger.debug('Kano World auth Exception: {}'.format(reason))
            pass

        if not loggedin:
            # Kano world auth unauthorized
            # FIXME: Localizing the below string fails with an exception
            GObject.idle_add(self._error_message_box,
                             'Failed to authenticate to Kano World', reason)
            return
        else:
            # We are authenticated to Kano World: proceed with forcing local user
            rc = -1
            try:
                # Create the local unix user, bypass kano-init-flow, login & sync to Kano World
                createuser_cmd = 'sudo /usr/bin/kano-greeter-account {} {} {}'.format(
                    self.unix_username, self.unix_password,
                    self.world_username)
                _, _, rc = run_cmd(createuser_cmd)
                if rc == 0:
                    logger.debug('Local user created correctly: {}'.format(
                        self.unix_username))
                elif rc == 1:
                    logger.debug(
                        'Local user already exists, proceeding with login: {}'.
                        format(self.unix_username))

                created = True
            except:
                created = False

            if not created:
                logger.debug('Error creating new local user: {}'.format(
                    self.unix_username))
                GObject.idle_add(self._error_message_box,
                                 "Could not create local user", rc)
                return

            # Tell Lidghtdm to proceed with login session using the new user
            # We bind LightDM at this point only, this minimizes the number of attempts
            # to bind the Greeter class to a view, which he does not like quite well.
            logger.debug('Scheduling lightdm authentication in math thread')
            GObject.idle_add(self._auth_call)

    def _auth_call(self):
        logger.debug('Starting lightdm authentication')
        self._reset_greeter()
        self.greeter.authenticate(self.unix_username)
        if self.greeter.get_is_authenticated():
            logger.debug('User is already authenticated, starting session')

    def _reset_greeter(self):
        # connect signal handlers to LightDM
        self.cb_one = self.greeter.connect('show-prompt',
                                           self._send_password_cb)
        self.cb_two = self.greeter.connect('authentication-complete',
                                           self._authentication_complete_cb)
        self.cb_three = self.greeter.connect('show-message',
                                             self._auth_error_cb)
        self.greeter.connect_sync()
        return (self.cb_one, self.cb_two, self.cb_three)

    def _send_password_cb(self, _greeter, text, prompt_type):
        logger.debug('Need to show prompt: {}'.format(text))
        if _greeter.get_in_authentication():
            logger.debug('Sending password to LightDM')
            _greeter.respond(self.unix_password)

    def _authentication_complete_cb(self, _greeter):
        logger.debug('Authentication process is complete')

        if not _greeter.get_is_authenticated():
            logger.warn('Could not authenticate user {}'.format(
                self.unix_username))
            self._auth_error_cb(
                _('Incorrect password (The default is "kano")'))
            return

        logger.info(
            'The user {} is authenticated. Starting LightDM X Session'.format(
                self.unix_username))

        set_last_user(self.unix_username)

        if not _greeter.start_session_sync('lightdm-xsession'):
            logger.error('Failed to start session')
        else:
            logger.info('Login failed')

    def _auth_error_cb(self, text, message_type=None):
        logger.info('There was an error logging in: {}'.format(text))

        win = self.get_toplevel()
        win.go_to_users()

        self.login_btn.stop_spinner()
        self.login_btn.set_sensitive(True)
        self.newuser_btn.set_sensitive(True)

        error = KanoDialog(title_text=_('Error Synchronizing account'),
                           description_text=text,
                           parent_window=self.get_toplevel())
        error.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        error.run()

    def _error_message_box(self, title, description):
        '''
        Show a standard error message box
        '''
        self.login_btn.stop_spinner()
        self.login_btn.set_sensitive(True)

        errormsg = KanoDialog(title_text=title,
                              description_text=description,
                              button_dict=[{
                                  'label': _('OK').upper(),
                                  'color': 'red',
                                  'return_value': True
                              }])

        errormsg.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        errormsg.run()

        # Clean up password field
        self.password.set_text('')
        return

    def grab_focus(self):
        '''
        Clear username and password previous text, and gain focus.
        '''
        self.username.set_text('')
        self.password.set_text('')
Exemplo n.º 49
0
class BluetoothDeviceItem(Gtk.Box):
    __gsignals__ = {
        'pairing': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ()),
        'done-pairing': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ()),
    }

    def __init__(self, device):
        Gtk.Box.__init__(self, hexpand=True)

        self.device = device
        device_name = device.name

        dev_label = Gtk.Label(device_name, hexpand=True)
        dev_label.get_style_context().add_class('normal_label')
        self.pack_start(dev_label, False, False, 0)

        self._pair_button = KanoButton()
        self._set_paired_button_state()
        self._pair_button.set_margin_top(10)
        self._pair_button.set_margin_bottom(10)
        self._pair_button.set_margin_left(10)
        self._pair_button.set_margin_right(10)
        self._pair_button.connect('clicked', self.pair)
        self.pack_start(self._pair_button, False, False, 0)

    def _set_paired_button_state(self, *dummy_args, **dummy_kwargs):
        if not self.device.connected:
            label = _("PAIR")
            colour = 'green'
        else:
            label = _("UNPAIR")
            colour = 'red'

        self._pair_button.set_label(label)
        self._pair_button.set_color(colour)

    def error(self, err_msg):
        KanoDialog(err_msg).run()

    def pair(self, *dummy_args, **dummy_kwargs):
        def done_pairing():
            self._set_paired_button_state()
            self.emit('done-pairing')

        @queue_cb(callback=done_pairing, gtk=True)
        def do_pair():
            if not self.device.fuse():
                GObject.idle_add(self.error, _("Pairing failed"))

        @queue_cb(callback=done_pairing, gtk=True)
        def do_unpair():
            if not self.device.unfuse():
                GObject.idle_add(self.error, _("Unpairing failed"))

        self.emit('pairing')

        if self.device.connected:
            pair_fn = do_unpair
            logger.info("Unpairing {}".format(self.device))
        else:
            pair_fn = do_pair
            logger.info("Pairing {}".format(self.device))

        pair_thr = threading.Thread(target=pair_fn)
        pair_thr.start()
Exemplo n.º 50
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.º 51
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.º 52
0
class SetWifi(Template):
    wifi_connection_attempted = False

    def __init__(self, win):

        Template.__init__(self, "", _("to be set"), _("COMPLETE"))

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

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

        internet_img = Gtk.Image()

        # Very hacky way to centre the Proxy button - put spaces in the label
        self.proxy_button = OrangeButton(_("Proxy  "))
        self.proxy_button.connect('button-release-event', self.go_to_proxy)
        self.disable_proxy = OrangeButton(_("Disable proxy"))

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

        internet_status = Gtk.Label()
        internet_status_style = internet_status.get_style_context()
        internet_status.set_alignment(xalign=1, yalign=0.5)

        internet_action = Gtk.Label()
        internet_action_style = internet_action.get_style_context()
        internet_status_style.add_class('internet_status_top')
        internet_action_style.add_class('internet_status_bottom')
        internet_action.set_alignment(xalign=1, yalign=0.5)

        status_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        status_box.props.valign = Gtk.Align.CENTER

        configure_container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)

        container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        container.pack_start(status_box, False, False, 2)
        container.pack_start(internet_img, False, False, 2)
        self.box.pack_start(container, False, False, 0)

        network_info_dict = network_info()
        common.has_internet = is_internet()

        if not common.has_internet or not network_info_dict:
            if network_info_dict:
                description = _("Use the browser to log in or configure proxy")
            else:
                description = _("Configure wireless")

            title = _("Get connected")

            self.add_connection = KanoButton(_("WIFI"))
            self.add_connection.connect('button_release_event', self.configure_wifi)
            # We removed the ability to use keyboard to click, so we also remove ability
            # to get keyboard focus
            self.add_connection.set_can_focus(False)

            # For now, this is removed as the event listener is interefering with the
            # kano-connect
            #self.add_connection.connect("key_release_event", self.configure_wifi)

            status_box.pack_start(self.add_connection, False, False, 0)
            internet_img.set_from_file(common.media + "/Graphics/Internet-noConnection.png")
            internet_status.set_text(_("No network found"))
            self.kano_button.set_label(_("BACK"))

            status_box.pack_start(configure_container, False, False, 3)

            go_to_portal_button = OrangeButton(_("Browser Login"))
            go_to_portal_button.connect('button-press-event', self.cb_launch_browser)
            configure_container.pack_start(go_to_portal_button, False, False, 0)

            divider_label = Gtk.Label("|")
            configure_container.pack_start(divider_label, False, False, 3)

            configure_container.pack_end(self.proxy_button, False, False, 0)

        else:
            self.kano_button.set_label(_("COMPLETE"))

            status_box.pack_start(internet_status, False, False, 3)
            status_box.pack_start(internet_action, False, False, 3)
            status_box.pack_start(configure_container, False, False, 3)

            network = network_info_dict.keys()[0]
            ip = network_info_dict[network]['address']
            network_text = network_info_dict[network]['nice_name']

            internet_img.set_from_file(common.media + "/Graphics/Internet-Connection.png")

            internet_status.set_text(network_text)
            internet_action.set_text(ip)

            go_to_portal_button = OrangeButton(_("Browser Login"))
            go_to_portal_button.connect('button-press-event', self.cb_launch_browser)
            configure_container.pack_start(go_to_portal_button, False, False, 0)

            if network_text == 'Ethernet':
                title = _("Connection found!")
                description = _("You're on a wired network")
                # Change to ethernet image here
                internet_img.set_from_file(common.media + "/Graphics/Internet-ethernetConnection.png")

            else:
                title = _("Connection found!")
                description = _("You're on a wireless network")

                divider_label = Gtk.Label("|")
                configure_container.pack_start(divider_label, False, False, 3)

                configure_button = OrangeButton(_("Configure"))
                configure_button.connect('button_press_event', self.configure_wifi)
                configure_container.pack_start(configure_button, False, False, 0)

            divider_label = Gtk.Label("|")
            configure_container.pack_start(divider_label, False, False, 3)
            configure_container.pack_end(self.proxy_button, False, False, 0)

        self.title.title.set_text(title)
        self.title.description.set_text(description)
        self.win.show_all()

    def cb_launch_browser(self, control, signal):
        # start the default browser to visit the default page
        launch_browser()

    def go_to_proxy(self, widget, event):
        self.win.clear_win()
        SetProxy(self.win)

    def configure_wifi(self, widget=None, event=None):
        # If is a mouse click event or key pressed is ENTER
        if not hasattr(event, 'keyval') or event.keyval == Gdk.KEY_Return:
            self.kano_button.set_sensitive(True)
            self.wifi_connection_attempted = True

            # Blur window
            self.win.blur()
            self.win.show_all()

            # Force blur to be shown
            while Gtk.events_pending():
                Gtk.main_iteration()

            # Call WiFi config
            os.system('/usr/bin/kano-wifi-gui')

            # Refresh window after WiFi Setup
            self.win.unblur()
            self.win.clear_win()
            SetWifi(self.win)
class RegistrationScreen(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.set_decorated(True)

        title = Heading(
            _("Kano World"),
            _("Choose a cool name and secure password")
        )
        self.pack_start(title.container, False, False, 0)

        self.data_screen = GetData()  # TODO: refactor this
        self.data_screen.connect('widgets-filled', self._enable_register_button)
        self.data_screen.connect('widgets-empty', self._disable_register_button)
        self.add(self.data_screen)

        self.register_button = KanoButton(_("JOIN KANO WORLD"))
        self.register_button.set_sensitive(False)
        self.register_button.set_margin_top(10)
        self.register_button.set_margin_left(30)
        self.register_button.set_margin_right(30)
        self.register_button.set_margin_bottom(30)
        self.register_button.connect('clicked', self._on_register_button)
        self.pack_end(self.register_button, False, False, 0)

        self.win.show_all()

    def _enable_register_button(self, widget=None):
        """
        """
        self.register_button.set_sensitive(True)

    def _disable_register_button(self, widget=None):
        """
        """
        self.register_button.set_sensitive(False)

    def _on_register_button(self, widget=None):  # TODO: refactor this
        """
        """
        if not is_internet():
            self._show_not_internet_dialog()
            return

        # Get the username, password and birthday
        data = self.data_screen.get_widget_data()
        email = data['email']
        username = data['username']

        # Validate that the email address format is correct
        email_error = validate_email(email)
        if email_error:
            self._show_error_dialog(_("Incorrect Email address"), email_error)
            return

        if not self._is_username_available(username):
            self._show_username_taken_dialog(username)
            return

        # We can save the username to kano-profile
        # Don't save password as this is private
        self.data_screen.save_username_and_birthday()  # TODO: rename this
        self.data_screen.cache_emails()
        data = self.data_screen.get_widget_data()

        # This means no threads are needed.
        while Gtk.events_pending():  # TODO: why is this needed?
            Gtk.main_iteration()

        # Try and register the account on the server
        password = data['password']
        success, text = register_(email, username, password,
                                  marketing_enabled=True)

        # This should no longer be needed, since this is checked in the first
        # screen. However there is a small chance someone could take the
        # username while the user is in the process of registering
        if not success:
            if text.strip() == _("Cannot register, problem: "
               "Username already registered"):

                self._show_username_taken_dialog(username)

            else:
                logger.info("problem with registration: {}".format(text))
                return_value = 'FAIL'
                self._create_dialog(
                    title=_("Houston, we have a problem"),
                    description=str(text)
                )
                track_data('world-registration-failed', {'reason': text})

        else:
            logger.info("registration successful")

            # saving hardware info and initial Kano version
            save_hardware_info()
            save_kano_version()

            # running kano-sync after registration
            logger.info("running kano-sync after successful registration")
            cmd = '{bin_dir}/kano-sync --sync -s'.format(bin_dir=bin_dir)
            run_bg(cmd)

            return_value = 'SUCCEED'
            self._create_dialog(
                title=_("Profile activated!"),
                description=_("Now you can share stuff, build your character, "
                              "and connect with friends.")
            )

        self.win.get_window().set_cursor(None)

        # Close the app if it was successful
        if return_value == 'SUCCEED':
            Gtk.main_quit()

    def _is_username_available(self, name):
        """
        Returns True if username is available, and False otherwise
        """
        # Use the endpoint api.kano.me/users/username/:name
        success, text, data = request_wrapper(
            'get',
            '/users/username/{}'.format(name),
            headers=content_type_json
        )

        if not success and text.strip() == "User not found":
            return True
        elif success:
            # Username is definitely taken
            return False
        else:
            # Maybe let the user know something went wrong? e.g. if there's no
            # internet, launch a dialog at this point
            return False

    def _create_dialog(self, title, description):  # TODO: refactor this
        kdialog = KanoDialog(
            title,
            description,
            parent_window=self.win
        )
        rv = kdialog.run()
        return rv

    def _show_error_dialog(self, title, description):  # TODO: refactor this
        kdialog = KanoDialog(
            title,
            description,
            parent_window=self.win
        )
        kdialog.run()

    def _show_username_taken_dialog(self, username):  # TODO: refactor this
        track_data('world-registration-username-taken', {'username': username})
        kd = KanoDialog(
            _("This username is taken!"),
            _("Try another one"),
            parent_window=self.win
        )
        kd.run()
        self.data_screen.username.set_text("")
        self.data_screen.validate_username()
        self._disable_register_button()
        self.data_screen.username.grab_focus()

    def _show_not_internet_dialog(self):  # TODO: refactor this
        kd = KanoDialog(
            _("You don't have internet"),
            _("Do you want to connect to WiFi?"),
            [
                {
                    'label': _("YES"),
                    'color': 'green',
                    'return_value': 0
                },
                {
                    'label': _("NO"),
                    'color': 'red',
                    'return_value': 1
                }
            ],
            parent_window=self.win
        )
        response = kd.run()

        # Close the dialog
        while Gtk.events_pending():  # TODO: why is this needed?
            Gtk.main_iteration()

        if response == 0:
            subprocess.Popen("sudo kano-wifi-gui", shell=True)