Esempio n. 1
0
class WaitFiscalAnswer(Dialog):#{{{

    def __init__(self, filename, title=None, timeout=10, interval=0.1):#{{{
        self.filename = filename
        self.interval = interval
        self.timeout = timeout

        if title is None:
            title = "IMPRIMIENDO"

        msg = Text("Esperando la respuesta de la Impresora Fiscal ...", align='left')
        self.eta = Text("", align='left')

        self.dummy = Text("")
        self.dummy._selectable = True
        self.dummy.keypress = lambda s,k : None

        self.buttons = Columns([
            AttrMap(Button("Seguir esperando", on_press=self.remove_buttons),'dialog.button', 'dialog.button.focus'),
            AttrMap(Button("Cancelar Impresion", on_press=lambda *w: self.quit()), 'dialog.button', 'dialog.button.focus'),
        ], dividechars=1)

        self.content = Pile([
            msg,
            Divider(),
            self.eta,
            self.dummy,
        ])

        self.__super.__init__(
            self.content,
            title=title,
            attr_style='dialog.waitfiscal',
            title_attr_style='dialog.waitfiscal.title',
            height=None,
            width=60,
        )
#}}}
    def run(self):#{{{
        self._start_time = datetime.now()
        self._last_option = time.time()
        return self.__super.run(alarm=(self.interval, self._alarm))
#}}}
    def _alarm(self, main_loop, user_data=None):#{{{
        if not os.path.exists(self.filename):
            self.update_status()
            main_loop.set_alarm_in(self.interval, self._alarm)
            return
        else:
            self.dialog_result = True
            self.quit()
#}}}
    def update_status(self):#{{{
        self.eta.set_text("Tiempo: %s" % get_elapsed_time(self._start_time))
        if type(self.content.widget_list[-1]) is Text:
            if (time.time() - self._last_option) > self.timeout:
                self.add_buttons()
#}}}
    def add_buttons(self):#{{{
        self.content.widget_list[-1] = self.buttons
        self.content.set_focus(self.buttons)
#}}}
    def remove_buttons(self, *btn):#{{{
        self._last_option = time.time()
        self.content.widget_list[-1] = self.dummy
        self.content.set_focus(self.dummy)
Esempio n. 2
0
class LoginWindow(WidgetWrap):

    signals = ['login', 'logout']

    def __init__(self, app, extra=None, get_user=None, max_time=30):
        self.app = app

        self.extra = extra
        self.get_user = get_user
        self.max_time = max_time
        self._create_widgets()

        self._out_count = 0
        self._evt_time = 0
        self._parent = None
        self._key_sig_id = None
        self._timeout_sig_id = None

        self.__super.__init__(self.login_widget)

    def _create_widgets(self):
        self._create_login_widget()

        if self.extra:
            widget = Frame(LineBox(self.login_widget), footer=self.extra)
        else:
            widget = LineBox(self.login_widget)

        self.overlay = Overlay(
            widget, None,
            'center', ('relative', 100),
            'middle', ('relative', 100),
        )

    def _create_login_widget(self):
        self.username_entry = Edit(align='right')
        self.username_entry.keypress = self._username_keypress
        self.password_entry = Password(align='right')
        self.password_entry.keypress = self._password_keypress

        username_row = Columns([
            ('fixed', 10, Text("Usuario:", align='right')),
            ('fixed', 10, self.username_entry),
        ])

        password_row = Columns([
            ('fixed', 10, Text("Clave:", align='right')),
            ('fixed', 10, self.password_entry),
        ])

        self.pile = Pile([
            username_row,
            Divider(),
            password_row,
        ], focus_item=0)

        self.login_widget = Filler(Columns([Divider(), self.pile, Divider()]))

    def show(self):
        """Show login window"""
        #self.pile.set_focus(0)
        self.clear()
        loop = self.app.loop
        self.overlay.bottom_w = loop.widget
        loop.widget = self.overlay
        if loop.screen.started:
            loop.draw_screen()

    def hide(self):
        """Hide login window"""
        loop = self.app.loop
        loop.widget = self.overlay.bottom_w
        if loop.screen.started:
            loop.draw_screen()

    def login(self, user):
        """
        Login the session, showing all content and hidding login window.
        """
        # connect esc-esc signal to logout
        widget = self.overlay.bottom_w
        widget.orig_keypress = widget.keypress
        widget.keypress = self._wrapped_keypress

        self._last_key_time = time.time()
        self._timeout_sig_id = self.app.loop.set_alarm_in(self.max_time+1,
                                                          self._check_logout)

        if hasattr(widget, 'set_user') and callable(widget.set_user):
            widget.set_user(user)
        self.hide()
        self._emit("login")

    def logout(self):
        """Logout the session, hidding all content and showing login window
        again.
        """
        # disconnect esc-esc signal
        self.app.loop.widget.keypress = self.app.loop.widget.orig_keypress

        self.app.loop.remove_alarm(self._timeout_sig_id)
        self.show()
        self._emit("logout")

    def clear(self):
        self.username_entry.set_edit_text("")
        self.password_entry.set_edit_text("")
        self.pile.set_focus(0)

    def _wrapped_keypress(self, size, key):
        self._last_key_time = time.time()
        if key == 'esc':
            if self._out_count == 1 and (time.time() - self._evt_time) < 1:
                self._out_count = 0
                self._evt_time = 0
                self.logout()
            else:
                self._out_count = 1
                self._evt_time = time.time()
            return None
        else:
            return self.app.loop.widget.orig_keypress(size, key)

    def _username_keypress(self, size, key):
        if key == 'enter':
            key = 'down'
        return self.username_entry.__class__.keypress(self.username_entry, size, key)

    def _password_keypress(self, size, key):
        if key == 'enter':
            password = self.password_entry.get_edit_text()
            username = self.username_entry.get_edit_text()
            self.password_entry.set_edit_text("")
            if password and username:
                user = self.get_user(username, password)
                if user:
                    #self.username_entry.set_edit_text("")
                    self.login(user)
            return
        return self.password_entry.__class__.keypress(self.password_entry, size, key)

    def _check_logout(self, main_loop, user_data=None):
        etime = int(time.time() - self._last_key_time)
        if etime >= self.max_time:
            self.logout()
        else:
            main_loop.remove_alarm(self._timeout_sig_id)
            self._timeout_sig_id = main_loop.set_alarm_in(self.max_time-etime, self._check_logout)
        return False
Esempio n. 3
0
class SelectClient(Dialog):

    def __init__(self, title=None, cls=None):
        if cls is None:
            cls = type('Dummy', (object,), {'__init__': lambda *a, **k: None, 'run': lambda *a: None})
        self.cls = cls
        self._obj = None

        _edit_cancel = lambda *w: self.focus_button(1)

        self.codigo_box = MaeterCodeBox(max_length=12, align='right')
        connect_signal(self.codigo_box, 'focus-in', highlight_focus_in),
        connect_signal(self.codigo_box, 'edit-done', self.on_codigo_edit_done)
        connect_signal(self.codigo_box, 'edit-cancel', _edit_cancel)
        connect_signal(self.codigo_box, 'search-client', self.on_client_search)

        self.nombre = Text(u'')

        client_row = Columns([
            ('fixed', 8, AttrMap(Text("Cliente", align='right'), 'dialog.selectdate.label')),
            ('fixed', 6, AttrMap(self.codigo_box, 'dialog.selectdate.input', 'dialog.selectdate.input.focus')),
            AttrMap(self.nombre, 'dialog.selectdate.label'),
        ], dividechars=1)

        self.content = Pile([
            client_row,
            Divider(),
        ])

        buttons = [("Continuar", self.run_list), ("Cancelar", self.quit)]

        self.__super.__init__(self.content, buttons,
                title=title or u'<Falta titulo>',
                height=None,
                width=60,
                attr_style='dialog.selectdate',
                title_attr_style='dialog.selectdate.title')

    def run_list(self, *args):
        if not self._obj:
            self._pile.set_focus(0)
            self.content.set_focus(0)
            return
        subdialog = self.cls(cliente=self._obj)
        self.dialog_result = subdialog.run()
        self.quit()

    def on_codigo_edit_done(self, widget, code):
        if code != u"":
            query = session.query(Cliente).filter(Cliente.codigo==int(code))
            query = query.filter(Cliente.relacion==u"C")
            try:
                self._obj = query.one()
                self.codigo_box.set_edit_text(self._obj.codigo)
                self.nombre.set_text(self._obj.nombre + " - " + self._obj.direccion)
                self.focus_button(0)
            except NoResultFound:
                self._obj = None
                self.nombre.set_text(u"")

    def on_client_search(self, widget, search_by=None, first_key=None):
        response = search_terceros(search_by=search_by, first_key=first_key)
        if response:
            self.codigo_box.set_edit_text(str(response[0].codigo))
            self.nombre.set_text(str(response[0].nombre))
            self.on_codigo_edit_done(self.codigo_box, str(response[0].codigo))
        return None
Esempio n. 4
0
class TreePile(WidgetWrap):
    _selectable = True

    def __init__(self, walker, **kwargs):
        if not isinstance(walker, TreeListWalker):
            walker = TreeListWalker(walker)
        self._walker = walker
        self._lines = []
        self.loadlines()
        logging.debug('lines:\n\n%s' % str(self._lines))
        self._pile = Pile(self._lines)
        self.__super.__init__(self._pile)

    def loadlines(self):
        widget, pos = self._walker.get_focus()
        while pos is not None:
            self._lines.append(widget)
            widget, pos = self._walker.get_next(pos)

    # Widget API
    def get_focus(self):
        return self._pile.get_focus()

    def keypress(self, size, key):
        key = self._pile.keypress(size, key)
        if key in ['left', 'right', '[', ']', '-', '+', 'C', 'E']:
            if key == 'left':
                self.focus_parent()
            elif key == 'right':
                self.focus_first_child()
            elif key == '[':
                self.focus_prev_sibling()
            elif key == ']':
                self.focus_next_sibling()
            if isinstance(self._walker, CollapseMixin):
                if key == '-':
                    w, focuspos = self._walker.get_focus()
                    self._walker.collapse(focuspos)
                elif key == '+':
                    w, focuspos = self._walker.get_focus()
                    self._walker.expand(focuspos)
                elif key == 'C':
                    self._walker.collapse_all()
                elif key == 'E':
                    self._walker.expand_all()
            # This is a hack around ListBox misbehaving:
            # it seems impossible to set the focus without calling keypress as
            # otherwise the change becomes visible only after the next render()
            return self._pile.keypress(size, None)
        else:
            return self._pile.keypress(size, key)

    # Tree based focus movement
    def focus_parent(self):
        w, focuspos = self._walker.get_focus()
        parent = self._walker.parent_position(focuspos)
        if parent is not None:
            self._pile.set_focus(parent)

    def focus_first_child(self):
        w, focuspos = self._walker.get_focus()
        child = self._walker.first_child_position(focuspos)
        if child is not None:
            self._outer_list.set_focus(child)

    def focus_next_sibling(self):
        w, focuspos = self._walker.get_focus()
        sib = self._walker.next_sibling_position(focuspos)
        if sib is not None:
            self._outer_list.set_focus(sib)

    def focus_prev_sibling(self):
        w, focuspos = self._walker.get_focus()
        sib = self._walker.prev_sibling_position(focuspos)
        if sib is not None:
            self._outer_list.set_focus(sib)
Esempio n. 5
0
class SelectArticlesDateRange(SelectDateRange):#{{{

    def __init__(self, title=None, cls=None):#{{{
        if cls is None:
            cls = type('Dummy', (object,), {'run': lambda *a: None})
        self.cls = cls

        self._desde_err = None
        self._hasta_err = None

        _edit_cancel = lambda *w: self.focus_button(1)
        _edit_ok = lambda *w: self.focus_button(0)
        def _focus_hasta(*w):
            self.content.set_focus(2)

        self.articulos = InputBox()
        self.articulos.filter_input = lambda t: t.upper()
        connect_signal(self.articulos, "edit-done", self.on_articulos_edit_done)
        connect_signal(self.articulos, "edit-cancel", _edit_cancel)

        self.desde = DateSelectorBox(out_fmt="%d/%m/%Y")
        err = ('desde_error', '_desde_err')
        connect_signal(self.desde, 'focus-in', self.on_fecha_focus_in, err)
        connect_signal(self.desde, 'focus-out', self.on_fecha_focus_out, err)
        connect_signal(self.desde, 'edit-cancel', _edit_cancel)
        connect_signal(self.desde, 'edit-done', self.on_fecha_edit_done, err+(_focus_hasta,))
        connect_signal(self.desde, 'bad-date-error', self.on_fecha_error, err)
        self.desde_error = Text("", wrap='clip')

        self.hasta = DateSelectorBox(out_fmt="%d/%m/%Y")
        err = ('hasta_error', '_hasta_err')
        connect_signal(self.hasta, 'focus-in', self.on_fecha_focus_in, err)
        connect_signal(self.hasta, 'focus-out', self.on_fecha_focus_out, err)
        connect_signal(self.hasta, 'edit-cancel', _edit_cancel)
        connect_signal(self.hasta, 'edit-done', self.on_fecha_edit_done, err+(_edit_ok,))
        connect_signal(self.hasta, 'bad-date-error', self.on_fecha_error, err)
        self.hasta_error = Text("", wrap='clip')

        articulos_row = Columns([
            ('fixed', 14, AttrMap(Text("Artículos", align='right'), 'dialog.selectdate.label')),
            AttrMap(self.articulos, 'dialog.selectdate.input', 'dialog.selectdate.input.focus'),
        ], dividechars=1)

        desde_row = Columns([
            ('fixed', 14, AttrMap(Text("Desde", align='right'), 'dialog.selectdate.label')),
            ('fixed', 11, AttrMap(self.desde, 'dialog.selectdate.input', 'dialog.selectdate.input.focus')),
            AttrMap(self.desde_error, 'dialog.selectdate.error'),
        ], dividechars=1)

        hasta_row = Columns([
            ('fixed', 14, AttrMap(Text("Hasta", align='right'), 'dialog.selectdate.label')),
            ('fixed', 11, AttrMap(self.hasta, 'dialog.selectdate.input', 'dialog.selectdate.input.focus')),
            AttrMap(self.hasta_error, 'dialog.selectdate.error'),
        ], dividechars=1)

        self.include_inactives = CheckBox(u"Incluir Desactivados", state=True)
        include_inactives_row = Columns([
            ('fixed', 14, Divider()),
            AttrMap(self.include_inactives, 'dialog.selectdate.label'),
        ], dividechars=1)

        self.content = Pile([
            articulos_row,
            desde_row,
            hasta_row,
            include_inactives_row,
            Divider(),
        ])

        t = u"Artículos y Rango de Fechas"
        if title:
            t += u" - %s" % title

        # Set initial dates
        self.desde.set_value(date(2001, 01, 01)) # FIXME: hardcoded > Principio de actividad
        self.hasta.set_value(date.today()+relativedelta(day=31)) # Fin de mes

        buttons = [("Continuar", self.run_list), ("Cancelar", self._quit)]

        Dialog.__init__(self, self.content, buttons,
                title=t,
                height=None,
                width=60,
                attr_style='dialog.selectdate',
                title_attr_style='dialog.selectdate.title')
#}}}
    def run_list(self, *args):
        art_list = self.get_articles()
        if not art_list:
            show_error([u"Los artículos ingresados no producen ningún resultado válido, ",
                        u"ingrese ", ('dialog.warning.important', u"artículos"), " o ",
                        ('dialog.warning.important', "grupos"), " correctos."])
            self._pile.set_focus(0)
            self.content.set_focus(0)
            return
        subdialog = self.cls(start_date=self.desde.get_value(),
                             end_date=self.hasta.get_value(),
                             articles=art_list)
        self.dialog_result = subdialog.run()
        self.quit()

    def get_articles(self):
        arts = []
        code_list = set([c.strip() for c in self.articulos.get_edit_text().split(",")])
        agrup_list = [c[1:] for c in code_list if c.startswith('@')]
        code_list = code_list.difference(agrup_list)
        query = session.query(Articulo)
        if self.include_inactives.get_state() is False:
            query = query.filter(Articulo.es_activo==True)
        if code_list:
            art = query.filter(Articulo.codigo.in_(code_list)).all()
            order = dict([(v, i) for i, v in enumerate(code_list)])
            art.sort(cmp=lambda a, b: cmp(order[a.codigo], order[b.codigo]))
            arts.extend(art)
        if agrup_list:
            art = query.filter(Articulo.agrupacion.in_(agrup_list)).order_by(Articulo.codigo).all()
            order = dict([(v, i) for i, v in enumerate(agrup_list)])
            art.sort(cmp=lambda a, b: cmp(order[a.agrupacion], order[b.agrupacion]))
            arts.extend(art)
        return arts

    def on_articulos_edit_done(self, widget, text):
        self.content.set_focus(1)