Add possibility to select the dialect of CSV export
You can also select a delimiter from a list
This commit is contained in:
parent
0d131a0c5c
commit
3b2d845992
@ -158,6 +158,9 @@ register('behavior.welcome', 100)
|
||||
register('behavior.web-search-url', 'http://google.com/#&q=%(text)s')
|
||||
register('behavior.addons-url', "https://raw.githubusercontent.com/gramps-project/addons/master/gramps52")
|
||||
|
||||
register('csv.dialect', 'excel')
|
||||
register('csv.delimiter', ',')
|
||||
|
||||
register('database.backend', 'sqlite')
|
||||
register('database.compress-backup', True)
|
||||
register('database.backup-path', USER_HOME)
|
||||
|
@ -30,9 +30,14 @@ import csv
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.config import config
|
||||
from .tabbeddoc import *
|
||||
from ...constfunc import win
|
||||
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
|
||||
class CSVTab(TabbedDoc):
|
||||
|
||||
def __init__(self, columns):
|
||||
@ -51,7 +56,12 @@ class CSVTab(TabbedDoc):
|
||||
|
||||
self.f = open(self.filename, "w", newline='',
|
||||
encoding='utf_8_sig' if win() else 'utf_8')
|
||||
self.writer = csv.writer(self.f)
|
||||
my_dialect = config.get('csv.dialect')
|
||||
my_delimiter = config.get('csv.delimiter')
|
||||
if my_dialect == _("Custom"):
|
||||
self.writer = csv.writer(self.f, delimiter=my_delimiter)
|
||||
else:
|
||||
self.writer = csv.writer(self.f, dialect=my_dialect)
|
||||
|
||||
def close(self):
|
||||
assert(self.f)
|
||||
|
156
gramps/gui/csvdialect.py
Normal file
156
gramps/gui/csvdialect.py
Normal file
@ -0,0 +1,156 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2021- Serge Noiraud
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# gui/columnorder.py
|
||||
|
||||
"""
|
||||
Handle the csv format when exporting views
|
||||
"""
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
import logging
|
||||
import csv
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# GTK modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from gi.repository import Gtk
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
__LOG = logging.getLogger(".CsvDialect")
|
||||
|
||||
CSV_DELIMITERS = {
|
||||
',': ',',
|
||||
';': ';',
|
||||
':': ':',
|
||||
'|': '|',
|
||||
'\t': _('Tab', 'character'),
|
||||
}
|
||||
|
||||
class CsvDialect(Gtk.Box):
|
||||
"""
|
||||
Use a custom format for csv export views
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Used to set the csv dialect.
|
||||
We add the possibility to add a custom model where we
|
||||
can change the delimiter.
|
||||
"""
|
||||
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
hbox.set_spacing(10)
|
||||
hbox.pack_start(Gtk.Label(label=_('Choose your dialect')), False,
|
||||
False, 0)
|
||||
comment = Gtk.Label(label=_('Changes are immediate.\n'
|
||||
'This is used when exporting views'
|
||||
' in CSV format.'))
|
||||
comment.set_justify(Gtk.Justification.LEFT)
|
||||
hbox.pack_start(comment, False, False, 0)
|
||||
hbox.pack_start(Gtk.Label(label=' '), False, True, 0)
|
||||
|
||||
self.pack_start(hbox, True, True, 0)
|
||||
|
||||
self.dialect = config.get('csv.dialect')
|
||||
self.delimiter = config.get('csv.delimiter')
|
||||
|
||||
self.dialects = csv.list_dialects()
|
||||
self.dialects.append(_("Custom"))
|
||||
self.buttons = []
|
||||
button = None
|
||||
self.entry = Gtk.ComboBox()
|
||||
|
||||
for dialect in self.dialects:
|
||||
title = dialect
|
||||
button = Gtk.RadioButton.new_with_mnemonic_from_widget(button,
|
||||
title)
|
||||
button.connect("toggled", self.on_toggled, self.entry)
|
||||
self.buttons.append(button)
|
||||
hbox.pack_start(button, False, True, 0)
|
||||
if dialect == self.dialect:
|
||||
button.set_active(True)
|
||||
|
||||
lwidget = Gtk.Label(label=_("Delimiter:"))
|
||||
hbox.pack_start(lwidget, False, False, 0)
|
||||
|
||||
store = Gtk.ListStore(str, str)
|
||||
default = 0
|
||||
for index, (key, value) in enumerate(CSV_DELIMITERS.items()):
|
||||
store.append((key, value))
|
||||
if key == self.delimiter:
|
||||
default = index
|
||||
self.entry.set_model(store)
|
||||
cell = Gtk.CellRendererText()
|
||||
self.entry.pack_start(cell, True)
|
||||
self.entry.add_attribute(cell, 'text', 1)
|
||||
self.entry.set_active(default)
|
||||
self.entry.set_hexpand(False)
|
||||
self.entry.connect('changed', self.on_changed)
|
||||
hbox.pack_start(self.entry, False, True, 0)
|
||||
if self.dialect == _("Custom"):
|
||||
self.entry.set_sensitive(True)
|
||||
else:
|
||||
self.entry.set_sensitive(False)
|
||||
|
||||
def on_changed(self, obj):
|
||||
"""
|
||||
called when a button state change
|
||||
save is immediate
|
||||
"""
|
||||
sep_iter = obj.get_active_iter()
|
||||
|
||||
if sep_iter is not None:
|
||||
model = obj.get_model()
|
||||
sep = model[sep_iter][0]
|
||||
config.set('csv.delimiter', sep)
|
||||
|
||||
def on_toggled(self, obj, entry):
|
||||
"""
|
||||
called when a button state change
|
||||
save is immediate
|
||||
"""
|
||||
if obj.get_active():
|
||||
button = obj.get_label()
|
||||
config.set('csv.dialect', button)
|
||||
if button == _("Custom"):
|
||||
entry.set_sensitive(True)
|
||||
else:
|
||||
entry.set_sensitive(False)
|
@ -58,6 +58,7 @@ from .pageview import PageView
|
||||
from .navigationview import NavigationView
|
||||
from ..uimanager import ActionGroup
|
||||
from ..columnorder import ColumnOrder
|
||||
from ..csvdialect import CsvDialect
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.db import DbTxn
|
||||
from gramps.gen.errors import WindowActiveError, FilterError, HandleError
|
||||
@ -1348,4 +1349,6 @@ class ListView(NavigationView):
|
||||
self.get_column_widths(),
|
||||
self.set_column_order,
|
||||
tree=not flat)
|
||||
return [columnpage]
|
||||
def csvdialect(configdialog):
|
||||
return _('CSV Dialect'), CsvDialect()
|
||||
return [columnpage, csvdialect]
|
||||
|
@ -33,7 +33,9 @@ plg = newplugin()
|
||||
plg.id = 'ex_csv'
|
||||
plg.name = _("Comma Separated Values Spreadsheet (CSV)")
|
||||
plg.name_accell = _("Comma _Separated Values Spreadsheet (CSV)")
|
||||
plg.description = _("CSV is a common spreadsheet format.")
|
||||
plg.description = _("CSV is a common spreadsheet format."
|
||||
"\nYou can change this behavior in the 'Configure active"
|
||||
" view' of any list-based view")
|
||||
plg.version = '1.0'
|
||||
plg.gramps_target_version = MODULE_VERSION
|
||||
plg.status = STABLE
|
||||
|
@ -51,6 +51,7 @@ LOG = logging.getLogger(".ExportCSV")
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.lib import EventType, Person
|
||||
from gramps.gen.lib.eventroletype import EventRoleType
|
||||
from gramps.gui.plug.export import WriterOptionBox
|
||||
@ -256,7 +257,12 @@ class CSVWriter:
|
||||
self.fp = open(self.filename, "w",
|
||||
encoding='utf_8_sig' if win() else 'utf_8',
|
||||
newline='')
|
||||
self.g = csv.writer(self.fp)
|
||||
my_dialect = config.get('csv.dialect')
|
||||
my_delimiter = config.get('csv.delimiter')
|
||||
if my_dialect == _("Custom"):
|
||||
self.g = csv.writer(self.fp, delimiter=my_delimiter)
|
||||
else:
|
||||
self.g = csv.writer(self.fp, dialect=my_dialect)
|
||||
except IOError as msg:
|
||||
msg2 = _("Could not create %s") % self.filename
|
||||
self.user.notify_error(msg2,str(msg))
|
||||
|
@ -269,8 +269,16 @@ class CSVParser:
|
||||
|
||||
def read_csv(self, filehandle):
|
||||
"Read the data from the file and return it as a list."
|
||||
my_dialect = config.get('csv.dialect')
|
||||
my_delimiter = config.get('csv.delimiter')
|
||||
try:
|
||||
data = [[r.strip() for r in row] for row in csv.reader(filehandle)]
|
||||
if my_dialect == _("Custom"):
|
||||
data = [[r.strip() for r in row]
|
||||
for row in csv.reader(filehandle,
|
||||
delimiter=my_delimiter)]
|
||||
else:
|
||||
data = [[r.strip() for r in row]
|
||||
for row in csv.reader(filehandle, dialect=my_dialect)]
|
||||
except csv.Error as err:
|
||||
self.user.notify_error(_('format error: line %(line)d: %(zero)s') % {
|
||||
'line' : csv.reader.line_num, 'zero' : err } )
|
||||
|
@ -383,6 +383,7 @@ gramps/gui/autocomp.py
|
||||
gramps/gui/clipboard.py
|
||||
gramps/gui/columnorder.py
|
||||
gramps/gui/configure.py
|
||||
gramps/gui/csvdialect.py
|
||||
gramps/gui/dbloader.py
|
||||
gramps/gui/dbman.py
|
||||
gramps/gui/dialog.py
|
||||
|
Loading…
Reference in New Issue
Block a user