Beispiel #1
0
class PuzzleWindow(PuzzleWindowBase):
    #FIXME: fix the docstring.
    """ Main window with all components. """
    def __init__(self, application, *args, **kwargs):
        self.Application = application
        self.AppArgs = self.Application.MyArgs

        # define and bind settings, options to a class variable
        global settings
        global options
        settings = SectionConfig(self.Application.id, self.__class__.__name__)
        options = OptionConfig(self.Application.id)
        self.settings = settings
        self.options = options

        self.targets = None  # Gtk.TargetList.new([])
        self.dragaction = Gdk.DragAction.PRIVATE
        self.number_picked = None
        self.init_picker_done = False

        super().__init__(self, *args, **kwargs)

    def _eb_drag_begin(self, widget, context):
        #print(dir(context))
        if len(widget.get_children()[0].get_label().strip()):
            self.number_picked = widget.my_tag
            #print(self.AppArgs.picker.subpixbufs[5].get_width())
        else:
            self.number_picked = None

    def _eb_drag_end(self, widget, context):
        self.number_picked = None

    def fill_pieces(self):
        """ Fill label with remaining pieces. """
        #do nothing if user has show_pieces=False
        if not self.listboxPieces.get_visible():
            return
        remaining_dict = self.puzzle.get_remaining()
        #print('remaining_dict',remaining_dict)
        thelistbox = self.listboxPieces
        allchildren = thelistbox.get_children()
        for achild in allchildren[:]:
            achild.destroy()
        label = Gtk.Label(_('Remaining numbers:'))
        thelistbox.add(label)
        label.set_visible(True)
        for number_counter in range(9):
            thestr1 = self.AppArgs.strings_to_use[number_counter + 1]
            remaining = 9 - remaining_dict[number_counter + 1]
            label = Gtk.Label(thestr1 * remaining)
            label.set_xalign(0)
            eb = Gtk.EventBox()
            eb.add(label)
            if remaining > 0:
                eb.connect('button-press-event', self.on_piece_pressed,
                           number_counter + 1)
                eb.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, self.targets,
                                   self.dragaction)
                #eb.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [Gtk.TargetEntry("the num", Gtk.TargetFlags.SAME_APP, x)], Gdk.DragAction.PRIVATE )
                eb.connect_after("drag-begin", self._eb_drag_begin)
                eb.drag_source_add_text_targets()
                eb.connect("drag-end", self._eb_drag_end)
                #eb.drag_source_set_icon_name("gtk-open")
                eb.drag_source_set_icon_pixbuf(
                    self.AppArgs.picker.subpixbufs[number_counter + 1])
                #print('fill_pieces', self.AppArgs.picker.subpixbufs[number_counter+1].get_width())
                label.set_tooltip_text(
                    _("Drag «{}» to the board...").format(thestr1))
            else:
                label.set_tooltip_text(
                    _("You have placed all «{}».").format(thestr1))
            thelistbox.add(eb)
            eb.set_visible(True)
            eb.my_tag = str(number_counter + 1)

            label.set_visible(True)

        label = Gtk.Label(str(remaining_dict[0]))
        label.set_xalign(0.5)
        eb = Gtk.EventBox()
        eb.add(label)
        thelistbox.insert(eb, 1)
        eb.set_visible(True)
        label.set_visible(True)
        theimage = Gtk.Image.new_from_icon_name("gtk-zoom-100",
                                                Gtk.IconSize.DND)
        theimage.set_visible(True)
        self.remaining_image = theimage
        thelistbox.add(theimage)
        #theimage.set_from_pixbuf ()

        self.listboxPieces.show_all()

    def on_piece_pressed(self, widget, event, *args):
        """ Handler for any piece.button-press-event.

        Triggered if label with remaining pieces is pressed. """
        #TODO: show all x's in the puzzle.
        #print('on_piece_pressed',args, self.AppArgs.picker.subpixbufs[args[0]].get_width())
        self.remaining_image.set_from_pixbuf(
            self.AppArgs.picker.subpixbufs[args[0]])
        return False

    def on_piece_released(self, widget, event, *args):
        """ Handler for any piece.button-release-event.

        Triggered if button on label with remaining pieces is released. """
        #TODO: reset "show all x's in the puzzle".
        #print('on_piece_released')
        #self.number_picked = None
        #return False
        pass

    def passed_time(self):
        """ Show time passed.

        Show time if option is enabled.
        Don't use this while playing history.
        """
        if self.playing_history:
            return False
        self.timepassed = datetime.datetime.utcnow() - self.timer_started
        allsecs = self.timepassed.seconds
        secs = int(allsecs % 60)
        mins = allsecs // 60 % 60
        hrs = allsecs // 3600
        #if diff.days:
        prefix = '>' if self.timepassed.days else ''
        tmp = prefix + '{0:02d}:{1:02d}:{2:02d}'.format(hrs, mins, secs)  #[:7]
        self.labelClock.set_label(tmp)
        return True and not self.exiting

    def picker_hide(self):
        '''Hide the picker. '''
        if self.is_picker_visible:
            self.AppArgs.picker.PickerWindow.hide()
            self.is_picker_visible = False

    def picker_resize(self, optional=None):
        if self.puzzle and self.puzzle.the_9:
            #set also best ratio
            if self.AppArgs.picker.PickerWindow.get_size(
            ) != self.puzzle.the_9 - 2:
                #self.picker_size = self.puzzle.the_9
                self.AppArgs.picker.image_resize(self.puzzle.the_9 - 2)
                self.fill_pieces()

    def picker_show(self, event, col, row):
        '''Show picker if not in constant cell. '''
        if self.puzzle.puzzlenums[self.puzzle.current_cell]['const']:
            return False
        if event.button == 1:
            #find window start
            window_x, window_y = self.PuzzleWindow.get_window(
            ).get_root_coords(0, 0)
            #find eventbox start
            full_size = self.eventboxPuzzle.get_allocation()
            #find working restangle start
            restangle_x = self.working_restangle.x + 5
            restangle_y = self.working_restangle.y + 5
            size = self.working_restangle.width - 10
            #the size of one cell
            the_9 = size / 9
            arow_x = the_9 * col
            arow_y = the_9 * row

            left = window_x + restangle_x + full_size.x + arow_x
            top = window_y + restangle_y + full_size.y + arow_y

            self.AppArgs.picker.PickerWindow.move(left, top)
            self.AppArgs.picker.PickerWindow.show_all()
            self.AppArgs.picker.PickerWindow.grab_focus()
            self.is_picker_visible = True
            return True

    def puzzle_continue(self):
        ''' Continue last saved game.

        If last game was solved start a new.
        If saved values are not valid start a new.
        If nothing was done start a new.
        '''
        self.puzzle = Puzzle(self.AppArgs.history.board,
                             self.AppArgs.strings_to_use,
                             self.AppArgs.font_scale,
                             self.AppArgs.history.history, self.AppArgs.font)
        self.puzzle.undos = options.get('last_undos', 0)
        self.puzzle.go_to_last_position()
        self.puzzle.check_puzzle()
        self.drawingareaPuzzle.queue_draw()
        self.set_undoredo()
        oldtimediff = datetime.timedelta(days=self.AppArgs.history.days,
                                         seconds=self.AppArgs.history.seconds)
        self.fill_pieces()
        self.timer_started = datetime.datetime.utcnow() - oldtimediff
        GObject.timeout_add(500, self.passed_time)

    def puzzle_move_cursor(self, tocell):
        '''Paint new selected cell. '''
        self.puzzle.puzzlenums[self.puzzle.current_cell]['sel'] = False

        self.puzzle.current_cell = tocell
        self.puzzle.puzzlenums[self.puzzle.current_cell]['sel'] = True
        self.drawingareaPuzzle.queue_draw()
        return True

    def puzzle_set_number(self, anumber=-1, undoredo=MOVE_NEW):
        '''Set a number in selected cell.

        If undo or redo is required use history.
        '''
        previousnum = self.puzzle.puzzlenums[self.puzzle.current_cell]['num']
        if undoredo == MOVE_NEW:
            if self.puzzle.undos:
                #remove all undos from history. We start a new node
                self.puzzle.history = self.puzzle.history[:-self.puzzle.undos]
                self.puzzle.undos = 0
            self.puzzle.puzzlenums[self.puzzle.current_cell]['num'] = anumber
            self.puzzle.append_to_history(previousnum)
        elif undoredo == MOVE_UNDO:
            self.puzzle.undos += 1
            lastplayed = self.puzzle.history[-self.puzzle.undos]
            lastcell = int(lastplayed[2:])
            previousnum = int(lastplayed[0])
            anumber = int(lastplayed[1:2])
            self.puzzle_move_cursor(lastcell)
            self.puzzle.puzzlenums[
                self.puzzle.current_cell]['num'] = previousnum
        elif undoredo == MOVE_REDO:
            lastplayed = self.puzzle.history[(len(self.puzzle.history) -
                                              self.puzzle.undos)]
            lastcell = int(lastplayed[2:])
            anumber = int(lastplayed[1:2])
            self.puzzle.undos -= 1
            self.puzzle_move_cursor(lastcell)
            self.puzzle.puzzlenums[self.puzzle.current_cell]['num'] = anumber
        self.puzzle.check_puzzle()
        self.drawingareaPuzzle.queue_draw()
        self.set_undoredo()
        self.fill_pieces()
        #print('filled after set a piece')
        #print(['{}:{},'.format(x, self.puzzle.puzzlenums[x]['num']) for x in self.puzzle.puzzlenums])
        if self.puzzle.solved:
            self.show_solved()
        return True

    def puzzle_start(self):
        '''Start a new puzzle. '''
        options.set('last_undos', 0)
        options.set('last_history', '')
        options.set('last_solved', False)
        options.set('last_board', self.AppArgs.current_board)
        self.puzzle = Puzzle(self.AppArgs.current_board,
                             self.AppArgs.strings_to_use,
                             self.AppArgs.font_scale, None, self.AppArgs.font)
        self.fill_pieces()
        self.timer_started = datetime.datetime.utcnow()
        GObject.timeout_add(500, self.passed_time)

    def response_from_picker(self, *args, **kwargs):
        '''Triggered from picker. '''
        #print(kwargs)
        self.is_picker_visible = False
        if kwargs['number_as_str'] != None and kwargs['number_as_str'] != '-1':
            self.puzzle_set_number(int(kwargs['number_as_str']))
        return True

    def set_undoredo(self):
        '''Write history in conf and show/hide undo-redo buttons. '''
        self.buttonUndo.set_sensitive(
            (len(self.puzzle.history) > 0
             and self.puzzle.undos < len(self.puzzle.history)))
        self.buttonRedo.set_sensitive(self.puzzle.undos > 0)

    def show_solved(self):
        """ Show that puzzle is solved and call exit window. """
        now = datetime.datetime.utcnow()
        #print('now,self.timer_started',now,self.timer_started)
        diff = now - self.timer_started
        #self.return_parameter = (True, str(diff)[2:7])

        if self.is_picker_visible:
            self.AppArgs.picker.PickerWindow.hide()
        self.exiting = True
        self.msg('{}\n ({}: {})'.format(_('Solved!'), _('time passed'),
                                        str(diff)[2:7]))
        self.exit_requested()

    def get_cell_number(self, widget, event):
        ebW = widget.get_allocated_width()
        imgW = ebW // 9  #self.image1.get_allocated_width()
        ebH = widget.get_allocated_height()
        imgH = ebH // 9  #self.image1.get_allocated_height()
        xstart = (ebW - imgW) // 2
        ystart = (ebH - imgH) // 2
        cellsize = int(imgW // 9)
        cellx = event.x // (imgH // 9)
        celly = event.y // (imgW // 9)
        if event.x > xstart and event.x < ebW - xstart:
            if event.y > ystart and event.y < ebH - ystart:
                thex = event.x - xstart
                they = event.y - ystart
                cell_number = 9 * (event.y //
                                   (imgW // 9)) + event.x // (imgH // 9) + 1
        else:
            cell_number = -1
        return int(cell_number), cellsize, cellx, celly
Beispiel #2
0
class PuzzleWindow(Gtk.Window):
    """ Main window with all components. """
    def __init__(self, app):
        # Set the app
        self.app = app

        # Basic initializations.
        self.we_can_exit_now = False
        self.return_parameter = (False, "00:00")
        self.picker = None
        self.picker_size = 10.
        self.previous_sel = None
        self.timer_started = None
        self.history_counter = 0
        self.playing_history = False

        #self.strings_to_use = [' ','α','β','γ','δ','ε','ς','ζ','η','θ']
        #self.strings_to_use = [' ','1','2','3','4','5','6','7','8','9']

        # Init the settings module.
        self.dummy_for_settings = SectionConfig(self.app.name,
                                                self.__class__.__name__)
        global settings
        settings = self.dummy_for_settings

        self.dummy_for_options = OptionConfig(self.app.name)
        global options
        options = self.dummy_for_options

        Gtk.Window.__init__(self)
        self.set_title(self.app.localizedname)

        # Initializations required before loading glade file.

        # Bind the locale.
        locale.bindtextdomain(self.app.domain,
                              os.path.join(self.app.BASE_DIR, 'locale'))
        locale.textdomain(self.app.domain)

        # Load app and window icon.
        self.set_icon(self.app.icon)

        # Bind message boxes.
        self.MessageBox = MessageBox(self)
        self.msg = self.MessageBox.Message

        # Glade stuff
        # Load Glade file to self
        self.builder = Gtk.Builder()
        try:
            self.builder.add_from_file(
                os.path.join(self.app.BASE_DIR, 'ui', 'puzzlewindow.glade'))
        except Exception as ex:
            print(str(ex))
            print('\n{}:\n{}\n{}'.format(
                _('Error loading from Glade file'),
                os.path.join(self.app.BASE_DIR, 'ui', 'puzzlewindow.glade'),
                repr(ex)))
            sys.exit(ERROR_INVALID_GLADE_FILE)

        # Get gui objects
        self.MainBox = self.builder.get_object('MainBox')
        self.boxTimer = self.builder.get_object('boxTimer')
        self.boxMenu = self.builder.get_object('boxMenu')
        self.buttonHome = self.builder.get_object('buttonHome')
        self.drawingareaPuzzle = self.builder.get_object('drawingareaPuzzle')
        self.eventboxPuzzle = self.builder.get_object('eventboxPuzzle')
        self.imageClock = self.builder.get_object('imageClock')
        self.labelClock = self.builder.get_object('labelClock')
        self.labelVersion = self.builder.get_object('labelVersion')
        self.listboxPieces = self.builder.get_object('listboxPieces')

        # Connect signals existing in the Glade file
        self.builder.connect_signals(self)

        # Reparent our main container from glader file,
        # this way we have all Gtk.Window functionality using "self"
        thechild = self.builder.get_object('PuzzleWindow').get_child()
        thechild.get_parent().remove(thechild)
        self.add(thechild)

        # Connect generated signals.
        self.buttonHome.connect('clicked', self.on_buttonHome_clicked)
        self.connect('delete-event', self.on_PuzzleWindow_delete_event)
        self.connect('destroy', self.on_PuzzleWindow_destroy)
        self.connect('key-release-event',
                     self.on_PuzzleWindow_key_release_event)
        self.connect('size-allocate', self.on_PuzzleWindow_size_allocate)
        self.connect('window-state-event',
                     self.on_PuzzleWindow_window_state_event)

        # Get any properties of top window.
        # Set the label for labelVersion
        self.labelVersion.set_label(VERSIONSTR)
        self.can_focus = 'False'

        # Load any settings or run extra initializations
        self.post_initialisations()

#********* Auto created "class defs" START ************************************************************
#********* Auto created handlers START *********************************

    def on_PuzzleWindow_delete_event(self, widget, event, *args):
        """ Handler for PuzzleWindow.delete-event. """
        self.set_unhandled_settings()
        return False

    def on_PuzzleWindow_destroy(self, widget, *args):
        """ Handler for PuzzleWindow.destroy. """
        if self.picker:
            self.picker.destroy()
        self.exit_requested()
        return False

    def on_PuzzleWindow_key_release_event(self, widget, event, *args):
        """ Handler for PuzzleWindow.key-release-event. """
        #if self.playing_history:
        #return False
        txt = Gdk.keyval_name(event.keyval)
        if type(txt) == type(None):
            return False
        txt = txt.replace('KP_', '')
        try:
            aunichar = chr(Gdk.keyval_to_unicode(event.keyval))
        except:
            aunichar = None
        if txt in ['Up', 'Down', 'Left', 'Right']:
            self.move_selection(['Up', 'Down', 'Left', 'Right'].index(txt))
        elif txt in [
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Delete'
        ] or txt in self.app.strings_to_use[1:]:
            self.set_num_in_selection(txt)
        elif aunichar and aunichar in self.app.strings_to_use[1:]:
            self.set_num_in_selection(aunichar)
        else:
            return False
        return True

    def on_PuzzleWindow_size_allocate(self, widget, allocation, *args):
        """ Handler for PuzzleWindow.size-allocate. """
        self.save_my_size()

    def on_PuzzleWindow_window_state_event(self, widget, event, *args):
        """ Handler for PuzzleWindow.window-state-event. """
        settings.set('maximized',
                     ((int(event.new_window_state) & Gdk.WindowState.ICONIFIED)
                      != Gdk.WindowState.ICONIFIED) and
                     ((int(event.new_window_state) & Gdk.WindowState.MAXIMIZED)
                      == Gdk.WindowState.MAXIMIZED))
        self.save_my_size()

    def on_buttonHome_clicked(self, widget, *args):
        """ Handler for buttonHome.clicked. """
        self.exit_requested()

    def on_drawingareaPuzzle_draw(self, widget, cr, *args):
        """ Handler for drawingareaPuzzle.draw. """
        w = widget.get_allocated_width()
        h = widget.get_allocated_height()
        b = self.puzzle.draw(cr, w, h)
        self.fill_pieces()

    def on_eventboxPuzzle_button_press_event(self, widget, event, *args):
        """ Handler for eventboxPuzzle.button-press-event. """
        self.picker_hide()

        col, rest = divmod(event.x - self.puzzle.startx, self.puzzle.the_9)
        row, rest = divmod(event.y - self.puzzle.starty, self.puzzle.the_9)

        if col >= 0 and row >= 0 and col < 9 and row < 9:
            blah = int(col) * 9 + int(row)
            if self.previous_sel != None:
                self.puzzle.puzzlenums[self.previous_sel]['sel'] = False
            self.puzzle.puzzlenums[blah]['sel'] = True
            self.previous_sel = blah
            self.drawingareaPuzzle.queue_draw()
            if not self.puzzle.puzzlenums[blah]['const']:
                if event.button == 3:
                    self.puzzle.puzzlenums[self.previous_sel]['num'] = 0
                    self.puzzle.append_to_history(
                        (self.previous_sel,
                         self.puzzle.puzzlenums[self.previous_sel]['num'],
                         self.labelClock.get_label()))
                elif event.button == 1:
                    left, top = self.get_position()
                    if self.picker_size != self.puzzle.the_9:
                        self.picker_size = self.puzzle.the_9
                        self.picker.resize(self.picker_size, self.picker_size)
                    self.picker.move(left + event.x, top + event.y)
                    response = self.picker.get_number()
                    if response:
                        self.puzzle.puzzlenums[self.previous_sel]['num'] = int(
                            response)
                        self.puzzle.append_to_history(
                            (self.previous_sel,
                             self.puzzle.puzzlenums[self.previous_sel]['num'],
                             self.labelClock.get_label()))
                else:
                    return False

            self.puzzle.check_puzzle()
            self.drawingareaPuzzle.queue_draw()
            if self.puzzle.solved:
                self.show_solved()
                return True
        else:
            print('outside')

#********* Auto created handlers  END **********************************

    def post_initialisations(self):
        """ Do some extra initializations.

        Display the version if a labelVersion is found.
        Set defaults (try to load them from a configuration file):
            - Window size and state (width, height and if maximized)
        Load other saved custom settings.
        """
        # Set previous size and state
        width = settings.get('width', 350)
        height = settings.get('height', 350)
        self.set_title(self.app.localizedname)
        self.resize(width, height)
        if settings.get_bool('maximized', False):
            self.maximize()

        # Load any other settings here.
        if self.app.show_simple:
            self.boxMenu.set_visible(not self.app.show_simple)
            self.boxMenu.set_no_show_all(True)
        if not self.app.show_pieces:
            self.listboxPieces.set_no_show_all(True)
        if not self.app.show_timer:
            self.boxTimer.set_no_show_all(True)
        self.listboxPieces.set_visible(self.app.show_pieces)
        self.imageClock.set_visible(self.app.show_timer)
        self.labelClock.set_visible(self.app.show_timer)
        if self.app.thehistory:  # history passed, user wants replay.
            self.set_sensitive(False)
            self.playing_history = True
            self.puzzle = Puzzle(self.app.puzzle_str, self.app.strings_to_use,
                                 self.app.font_scale, self.app.thehistory)
        else:
            self.start_puzzle()

    def set_unhandled_settings(self):
        """ Set, before exit, settings not applied during the session.

        Mass set some non critical settings for widgets
        (which where not setted when some widget's state changed).
        """
        #custom settings
        history_str = str(self.puzzle.history)
        #history_str = history_str.replace("'",'"')
        #history_json = json.loads(history_str)
        #history_json_str = json.dump(history_json)
        #history_str = history_json_str
        #print()
        history_str = history_str.replace("}}, ", "}},\n ")
        history_str = history_str.replace("), ", "),\n ")
        options.set('last_history', history_str)

    def save_my_size(self):
        """ Save the window size into settings if not maximized. """
        if not settings.get_bool('maximized', False):
            width, height = self.get_size()
            settings.set('width', width)
            settings.set('height', height)

    def exit_requested(self, *args):
        """ Set the param in order to exit from "run" method. """
        self.set_transient_for()
        self.set_modal(False)
        self.set_unhandled_settings()
        self.we_can_exit_now = True
        self.destroy()  #Will not call Handler for delete-event

    def run(self):
        """ Start the main loop.

        WARNING:
            The "destroy" event of the main window
            MUST set the "we_can_exit_now" to True,
            else program will never exit.
        Save settings on exit.
        Return "return_parameter" on exit.
        """
        #now we can show the main window.
        self.show_all()
        #self.boxMenu.set_visible(not self.app.show_simple)
        #self.set_interactive_debugging (True)
        if self.app.thehistory:
            GObject.timeout_add(1000, self.play_history)
        while True:
            if self.we_can_exit_now:
                break
            while Gtk.events_pending():
                Gtk.main_iteration()
        settings.save()
        return self.return_parameter

#********* Auto created "class defs" END **************************************************************

    def on_piece_pressed(self, widget, event, *args):
        """ Handler for any piece.button-press-event. """
        print('pressed piece:', args[0])

    def show_solved(self):
        """ Show a message and call exit window. """
        now = datetime.datetime.utcnow()
        print('now,self.timer_started', now, self.timer_started)
        diff = now - self.timer_started
        self.return_parameter = (True, str(diff)[2:7])
        self.msg('{}\n ({}: {})'.format(_('Solved!'), _('time passed'),
                                        self.return_parameter[1]))
        self.exit_requested()

    def set_num_in_selection(self, txt):
        """ Pokes the num in the puzzlenums dictionary. """
        self.picker_hide()
        sel = self.puzzle.puzzlenums[self.previous_sel]
        if sel['const']:
            return
        if txt in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
            sel['num'] = int(txt)
        elif txt in self.app.strings_to_use[1:]:
            sel['num'] = self.app.strings_to_use.index(txt)
        elif txt == 'Delete':
            sel['num'] = 0
        else:
            return
        self.puzzle.append_to_history(
            (self.previous_sel, sel['num'], self.labelClock.get_label()))
        self.puzzle.check_puzzle()
        self.drawingareaPuzzle.queue_draw()
        if self.puzzle.solved:
            self.show_solved()

    def move_selection(self, where):
        """ Move selection to cell based on key pressed. """
        self.picker_hide()
        if self.previous_sel == None:
            self.previous_sel = 0
            self.puzzle.puzzlenums[0]['sel'] = True
            self.drawingareaPuzzle.queue_draw()
        else:
            sel = -1
            if where == 0:
                sel = self.previous_sel - 1
            elif where == 1:
                sel = self.previous_sel + 1
            elif where == 2:
                sel = self.previous_sel - 9
            elif where == 3:
                sel = self.previous_sel + 9
            if sel >= 0 and sel <= 80:
                self.puzzle.puzzlenums[self.previous_sel]['sel'] = False
                self.previous_sel = sel
                self.puzzle.puzzlenums[self.previous_sel]['sel'] = True
                self.drawingareaPuzzle.queue_draw()

    def picker_hide(self):
        """ Hide the picker, if any. """
        if self.picker:
            self.picker.hide()

    def fill_pieces(self):
        """ Fill label with remaining pieces. """
        if not self.listboxPieces.get_visible():
            return
        thelistbox = self.listboxPieces
        allchildren = thelistbox.get_children()
        for achild in allchildren[:]:
            achild.destroy()
        label = Gtk.Label(_('Remaining:'))
        thelistbox.add(label)
        label.set_visible(True)
        for x in range(9):
            label = Gtk.Label("<" + self.app.strings_to_use[x + 1] + '>: ' +
                              str(9 - self.puzzle.pieces[x + 1]))
            eb = Gtk.EventBox()
            eb.connect("button-press-event", self.on_piece_pressed, x)
            eb.add(label)
            thelistbox.add(eb)
            eb.set_visible(True)
            label.set_visible(True)

        label = Gtk.Label("<.>: " + str(self.puzzle.pieces[0]))
        eb = Gtk.EventBox()
        eb.add(label)
        thelistbox.add(eb)
        eb.set_visible(True)
        label.set_visible(True)

    def start_puzzle(self):
        self.picker = NumberPicker(self, thelist=self.app.strings_to_use)
        self.picker.set_type_hint(Gdk.WindowTypeHint.DIALOG)
        self.puzzle = Puzzle(self.app.puzzle_str, self.app.strings_to_use,
                             self.app.font_scale)
        self.timer_started = datetime.datetime.utcnow()
        GObject.timeout_add(500, self.show_time_passed)

    def play_history(self):
        if self.history_counter >= len(self.app.thehistory) - 1:
            # Set to continue
            print('CONTINUE')
            self.playing_history = False
            self.picker = NumberPicker(self, thelist=self.app.strings_to_use)
            self.picker.set_type_hint(Gdk.WindowTypeHint.DIALOG)
            # set the timer
            timestr = self.labelClock.get_label()
            b = datetime.timedelta(seconds=int(timestr[:2]) * 60 +
                                   int(timestr[3:]))
            self.timer_started = datetime.datetime.utcnow() - b
            self.puzzle.check_puzzle()
            if self.puzzle.solved:
                #self.return_parameter = (True, self.labelClock.get_label())
                self.show_solved()
            else:
                self.puzzle.check_puzzle()
                GObject.timeout_add(500, self.show_time_passed)
                self.set_sensitive(True)
            return False
        self.history_counter += 1
        amove = self.app.thehistory[self.history_counter]
        self.puzzle.puzzlenums[amove[0]]['num'] = amove[1]
        self.labelClock.set_label(amove[2])
        self.puzzle.check_puzzle()
        self.drawingareaPuzzle.queue_draw()
        return True

    def show_time_passed(self):
        """ Show time passed.

        Only works if option is enabled.
        """
        if self.playing_history:
            return False
        diff = datetime.datetime.utcnow() - self.timer_started
        tmp = str(diff)[2:7]
        self.return_parameter = (self.return_parameter[0], tmp)
        self.labelClock.set_label(tmp)
        return True and not self.we_can_exit_now