Beispiel #1
0
 def format_row(cls, line, indent=0, locale_format=True):
     row = []
     for i, val in enumerate(line):
         if locale_format:
             if isinstance(val, Number):
                 val = locale.str(val)
             elif isinstance(val, datetime.datetime):
                 val = val.strftime(common.date_format() + ' %X')
             elif isinstance(val, datetime.date):
                 val = val.strftime(common.date_format())
             elif isinstance(val, datetime.timedelta):
                 val = common.timedelta.format(val, {
                     's': 1,
                     'm': 60,
                     'h': 60 * 60
                 })
         elif isinstance(val, datetime.timedelta):
             val = val.total_seconds()
         elif isinstance(val, bool):
             val = int(val)
         if i == 0 and indent and isinstance(val, str):
             val = '  ' * indent + val
         if isinstance(val, bytes):
             val = base64.b64encode(val).decode('utf-8')
         row.append(val)
     return row
Beispiel #2
0
 def format_row(cls, line, locale_format=True):
     row = []
     for val in line:
         if locale_format:
             if isinstance(val, Number):
                 val = locale.str(val)
             elif isinstance(val, datetime.datetime):
                 val = val.strftime(common.date_format() + ' %X')
             elif isinstance(val, datetime.date):
                 val = val.strftime(common.date_format())
         elif isinstance(val, bool):
             val = int(val)
         row.append(val)
     return row
Beispiel #3
0
 def set_format(self):
     if self.field and self.record:
         format_ = self.field.date_format(self.record)
     else:
         format_ = common.date_format(
             self.view.screen.context.get('date_format'))
     self.entry.props.format = format_
Beispiel #4
0
 def set_format(self, record, field):
     if field and record:
         format_ = field.date_format(record)
     else:
         format_ = common.date_format(
             self.view.screen.context.get('date_format'))
     self.entry.props.format = format_
Beispiel #5
0
 def convert_date():
     if not value:
         return
     format_ = date_format(context.get('date_format'))
     try:
         return date_parse(value, format_).date()
     except (ValueError, TypeError):
         return
Beispiel #6
0
 def convert_datetime():
     if not value:
         return
     format_ = (date_format(context.get('date_format')) + ' ' +
                time_format(field))
     try:
         dt = date_parse(value, format_)
         return untimezoned_date(dt)
     except ValueError:
         return
Beispiel #7
0
 def set_format(self):
     if self.field and self.record:
         date_format = self.field.date_format(self.record)
         time_format = self.field.time_format(self.record)
     else:
         date_format = common.date_format(
             self.view.screen.context.get('date_format'))
         time_format = '%X'
     self.entry.props.date_format = date_format
     self.entry.props.time_format = time_format
Beispiel #8
0
 def format_datetime():
     if not value:
         return ''
     if not isinstance(value, datetime.datetime):
         time = datetime.datetime.combine(value, datetime.time.min)
     else:
         time = timezoned_date(value)
     format_ = date_format(context.get('date_format'))
     if time.time() != datetime.time.min:
         format_ += ' ' + time_format(field)
     return time.strftime(format_)
Beispiel #9
0
    def export_csv(self, fname, fields, data, popup=True):
        encoding = self.csv_enc.get_active_text() or 'UTF-8'
        locale_format = self.csv_locale.get_active()

        try:
            writer = csv.writer(open(fname, 'w', encoding=encoding,
                                     newline=''),
                                quotechar=self.get_quotechar(),
                                delimiter=self.get_delimiter())
            if self.add_field_names.get_active():
                writer.writerow(fields)
            for line in data:
                row = []
                for val in line:
                    if locale_format:
                        if isinstance(val, Number):
                            val = locale.str(val)
                        elif isinstance(val, datetime.datetime):
                            val = val.strftime(common.date_format() + ' %X')
                        elif isinstance(val, datetime.date):
                            val = val.strftime(common.date_format())
                    elif isinstance(val, bool):
                        val = int(val)
                    row.append(val)
                writer.writerow(row)
            if popup:
                if len(data) == 1:
                    common.message(_('%d record saved.') % len(data))
                else:
                    common.message(_('%d records saved.') % len(data))
            return True
        except IOError as exception:
            common.warning(
                _("Operation failed.\nError message:\n%s") % exception,
                _('Error'))
            return False
Beispiel #10
0
 def import_csv(self, fname, fields):
     # TODO: make it works with references
     skip = self.csv_skip.get_value_as_int()
     encoding = self.get_encoding()
     locale_format = self.csv_locale.get_active()
     try:
         reader = csv.reader(open(fname, 'r', encoding=encoding),
                             quotechar=self.get_quotechar(),
                             delimiter=self.get_delimiter())
         data = []
         for i, line in enumerate(reader):
             if i < skip or not line:
                 continue
             row = []
             for field, val in zip(fields, line):
                 if locale_format and val:
                     type_ = self.fields_data[field]['type']
                     if type_ in ['integer', 'biginteger']:
                         val = locale.atoi(val)
                     elif type_ == 'float':
                         val = locale.atof(val)
                     elif type_ == 'numeric':
                         val = Decimal(locale.delocalize(val))
                     elif type_ in ['date', 'datetime']:
                         val = date_parse(val, common.date_format())
                     elif type_ == 'binary':
                         val = base64.b64decode(val)
                 row.append(val)
             data.append(row)
     except (IOError, UnicodeDecodeError, csv.Error) as exception:
         common.warning(str(exception), _("Import failed"))
         return
     try:
         count = RPCExecute('model',
                            self.model,
                            'import_data',
                            fields,
                            data,
                            context=self.context)
     except RPCException:
         return
     if count == 1:
         common.message(_('%d record imported.') % count)
     else:
         common.message(_('%d records imported.') % count)
Beispiel #11
0
 def format_date():
     if not value:
         return ''
     format_ = date_format(context.get('date_format'))
     return value.strftime(format_)
Beispiel #12
0
    def search_box(self, widget):
        def window_hide(window, *args):
            window.hide()
            self.search_entry.grab_focus()

        def key_press(widget, event):
            if event.keyval == gtk.keysyms.Escape:
                window_hide(widget)
                return True
            return False

        def search():
            self.search_window.hide()
            text = ''
            for label, entry in self.search_table.fields:
                if isinstance(entry, gtk.ComboBox):
                    value = quote(entry.get_active_text()) or None
                elif isinstance(entry, (Dates, Selection)):
                    value = entry.get_value()
                else:
                    value = quote(entry.get_text()) or None
                if value is not None:
                    text += quote(label) + ': ' + value + ' '
            self.set_text(text)
            self.do_search()
            # Store text after doing the search
            # because domain parser could simplify the text
            self.last_search_text = self.get_text()

        if not self.search_window:
            self.search_window = gtk.Window()
            Main().add_window(self.search_window)
            self.search_window.set_transient_for(widget.get_toplevel())
            self.search_window.set_type_hint(
                gtk.gdk.WINDOW_TYPE_HINT_POPUP_MENU)
            self.search_window.set_destroy_with_parent(True)
            self.search_window.set_decorated(False)
            self.search_window.set_deletable(False)
            self.search_window.connect('delete-event', window_hide)
            self.search_window.connect('key-press-event', key_press)
            self.search_window.connect('focus-out-event', window_hide)

            def toggle_window_hide(combobox, shown):
                if combobox.props.popup_shown:
                    self.search_window.handler_block_by_func(window_hide)
                else:
                    self.search_window.handler_unblock_by_func(window_hide)

            vbox = gtk.VBox()
            fields = [
                f for f in self.screen.domain_parser.fields.values()
                if f.get('searchable', True)
            ]
            self.search_table = gtk.Table(rows=len(fields), columns=2)
            self.search_table.set_homogeneous(False)
            self.search_table.set_border_width(5)
            self.search_table.set_row_spacings(2)
            self.search_table.set_col_spacings(2)

            # Fill table with fields
            self.search_table.fields = []
            for i, field in enumerate(fields):
                label = gtk.Label(field['string'])
                label.set_alignment(0.0, 0.0)
                self.search_table.attach(label,
                                         0,
                                         1,
                                         i,
                                         i + 1,
                                         yoptions=gtk.FILL)
                yoptions = False
                if field['type'] == 'boolean':
                    if hasattr(gtk, 'ComboBoxText'):
                        entry = gtk.ComboBoxText()
                    else:
                        entry = gtk.combo_box_new_text()
                    entry.connect('notify::popup-shown', toggle_window_hide)
                    entry.append_text('')
                    selections = (_('True'), _('False'))
                    for selection in selections:
                        entry.append_text(selection)
                elif field['type'] == 'selection':
                    selections = tuple(x[1] for x in field['selection'])
                    entry = Selection(selections)
                    yoptions = gtk.FILL | gtk.EXPAND
                elif field['type'] in ('date', 'datetime', 'time'):
                    date_format = common.date_format(
                        self.screen.context.get('date_format'))
                    if field['type'] == 'date':
                        entry = Dates(date_format)
                    elif field['type'] in ('datetime', 'time'):
                        time_format = PYSONDecoder({}).decode(field['format'])
                        if field['type'] == 'time':
                            entry = Times(time_format)
                        elif field['type'] == 'datetime':
                            entry = DateTimes(date_format, time_format)
                    entry.connect_activate(lambda *a: search())
                    entry.connect_combo(toggle_window_hide)
                else:
                    entry = gtk.Entry()
                    entry.connect('activate', lambda *a: search())
                label.set_mnemonic_widget(entry)
                self.search_table.attach(entry,
                                         1,
                                         2,
                                         i,
                                         i + 1,
                                         yoptions=yoptions)
                self.search_table.fields.append((field['string'], entry))

            scrolled = gtk.ScrolledWindow()
            scrolled.add_with_viewport(self.search_table)
            scrolled.set_shadow_type(gtk.SHADOW_NONE)
            scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
            vbox.pack_start(scrolled, expand=True, fill=True)
            find_button = gtk.Button(_('Find'))
            find_button.connect('clicked', lambda *a: search())
            find_button.set_image(
                common.IconFactory.get_image('tryton-search',
                                             gtk.ICON_SIZE_SMALL_TOOLBAR))
            hbuttonbox = gtk.HButtonBox()
            hbuttonbox.set_spacing(5)
            hbuttonbox.pack_start(find_button)
            hbuttonbox.set_layout(gtk.BUTTONBOX_END)
            vbox.pack_start(hbuttonbox, expand=False, fill=True)
            self.search_window.add(vbox)
            vbox.show_all()

            new_size = list(
                map(
                    sum,
                    list(
                        zip(self.search_table.size_request(),
                            scrolled.size_request()))))
            self.search_window.set_default_size(*new_size)

        parent = widget.get_toplevel()
        widget_x, widget_y = widget.translate_coordinates(parent, 0, 0)
        widget_allocation = widget.get_allocation()

        # Resize the window to not be out of the parent
        width, height = self.search_window.get_default_size()
        allocation = parent.get_allocation()
        delta_width = allocation.width - (widget_x + width)
        delta_height = allocation.height - (widget_y +
                                            widget_allocation.height + height)
        if delta_width < 0:
            width += delta_width
        if delta_height < 0:
            height += delta_height
        self.search_window.resize(width, height)

        # Move the window under the button
        if hasattr(widget.window, 'get_root_coords'):
            x, y = widget.window.get_root_coords(widget_allocation.x,
                                                 widget_allocation.y)
        else:
            x, y = widget.window.get_origin()
        self.search_window.move(x, y + widget_allocation.height)
        self.search_window.show()
        self.search_window.grab_focus()

        if self.last_search_text.strip() != self.get_text().strip():
            for label, entry in self.search_table.fields:
                if isinstance(entry, gtk.ComboBox):
                    entry.set_active(-1)
                elif isinstance(entry, Dates):
                    entry.set_values(None, None)
                elif isinstance(entry, Selection):
                    entry.treeview.get_selection().unselect_all()
                else:
                    entry.set_text('')
            if self.search_table.fields:
                self.search_table.fields[0][1].grab_focus()
Beispiel #13
0
 def date_format(self, record):
     context = self.get_context(record)
     return common.date_format(context.get('date_format'))
Beispiel #14
0
    def search_box(self, widget):
        def window_hide(window, *args):
            window.hide()
            self.search_entry.grab_focus()

        def search():
            self.search_popover.popdown()
            text = ''
            for label, entry in self.search_grid.fields:
                if isinstance(entry, Gtk.ComboBoxText):
                    value = quote(entry.get_active_text()) or None
                elif isinstance(entry, (Between, Selection)):
                    value = entry.get_value()
                else:
                    value = quote(entry.get_text()) or None
                if value is not None:
                    text += quote(label) + ': ' + value + ' '
            self.set_text(text)
            self.do_search()
            # Store text after doing the search
            # because domain parser could simplify the text
            self.last_search_text = self.get_text()

        if not self.search_popover:
            self.search_popover = Gtk.Popover()
            self.search_popover.set_relative_to(widget)

            vbox = Gtk.VBox()
            fields = [
                f for f in self.screen.domain_parser.fields.values()
                if f.get('searchable', True) and '.' not in f['name']
            ]
            self.search_grid = Gtk.Grid(column_spacing=3, row_spacing=3)

            # Fill table with fields
            self.search_grid.fields = []
            for i, field in enumerate(fields):
                label = Gtk.Label(label=field['string'],
                                  halign=Gtk.Align.START,
                                  valign=Gtk.Align.START)
                self.search_grid.attach(label, 0, i, 1, 1)
                if field['type'] == 'boolean':
                    entry = Gtk.ComboBoxText()
                    entry.append_text('')
                    selections = (_('True'), _('False'))
                    for selection in selections:
                        entry.append_text(selection)
                elif field['type'] in ['selection', 'multiselection']:
                    selections = tuple(x[1] for x in field['selection'])
                    entry = Selection(selections)
                    entry.set_vexpand(True)
                elif field['type'] in ('date', 'datetime', 'time'):
                    date_format = common.date_format(
                        self.screen.context.get('date_format'))
                    if field['type'] == 'date':
                        entry = Dates(date_format)
                    elif field['type'] in ('datetime', 'time'):
                        time_format = PYSONDecoder({}).decode(field['format'])
                        if field['type'] == 'time':
                            entry = Times(time_format)
                        elif field['type'] == 'datetime':
                            entry = DateTimes(date_format, time_format)
                    entry.connect('activate', lambda *a: search())
                elif field['type'] in ['integer', 'float', 'numeric']:
                    entry = Numbers()
                    entry.connect('activate', lambda *a: search())
                else:
                    entry = Gtk.Entry()
                    entry.connect('activate', lambda *a: search())
                label.set_mnemonic_widget(entry)
                self.search_grid.attach(entry, 1, i, 1, 1)
                self.search_grid.fields.append((field['string'], entry))

            scrolled = Gtk.ScrolledWindow()
            scrolled.add(self.search_grid)
            scrolled.set_shadow_type(Gtk.ShadowType.NONE)
            scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
            vbox.pack_start(scrolled, expand=True, fill=True, padding=0)
            find_button = Gtk.Button(label=_('Find'))
            find_button.connect('clicked', lambda *a: search())
            find_button.set_image(
                common.IconFactory.get_image('tryton-search',
                                             Gtk.IconSize.SMALL_TOOLBAR))
            find_button.set_can_default(True)
            self.search_popover.set_default_widget(find_button)
            hbuttonbox = Gtk.HButtonBox()
            hbuttonbox.pack_start(find_button,
                                  expand=False,
                                  fill=False,
                                  padding=0)
            hbuttonbox.set_layout(Gtk.ButtonBoxStyle.END)
            vbox.pack_start(hbuttonbox, expand=False, fill=True, padding=0)
            self.search_popover.add(vbox)
            vbox.show_all()
            scrolled.set_size_request(
                -1, min(self.search_grid.get_preferred_height()[1], 400))

        self.search_popover.set_pointing_to(
            widget.get_icon_area(Gtk.EntryIconPosition.PRIMARY))
        self.search_popover.popup()
        if self.search_grid.fields:
            self.search_grid.fields[0][1].grab_focus()

        if self.last_search_text.strip() != self.get_text().strip():
            for label, entry in self.search_grid.fields:
                if isinstance(entry, Gtk.ComboBoxText):
                    entry.set_active(-1)
                elif isinstance(entry, Between):
                    entry.set_value(None, None)
                elif isinstance(entry, Selection):
                    entry.treeview.get_selection().unselect_all()
                else:
                    entry.set_text('')