Merge branch 'master' into geps/gep-032-database-backend

This commit is contained in:
Doug Blank 2015-05-24 19:04:57 -04:00
commit e0e3cee255
8 changed files with 437 additions and 53 deletions

View File

@ -3,11 +3,11 @@
"http://gramps-project.org/xml/1.6.0/grampsxml.dtd">
<database xmlns="http://gramps-project.org/xml/1.6.0/">
<header>
<created date="2014-11-13" version="4.1.0"/>
<created date="2015-05-10" version="4.1.4"/>
<researcher>
<resname>Alex Roitman,,,</resname>
</researcher>
<mediapath>/home/cristina/gramps/master/example/gramps</mediapath>
<mediapath>/home/pierre/Gramps/master/example/gramps</mediapath>
</header>
<name-formats>
<format number="-1" name="SURNAME, Given (Common)" fmt_str="SURNAME, given (common)" active="1"/>
@ -91,6 +91,11 @@
<dateval val="1592" type="about"/>
<description>Birth of Abbott, Frances</description>
</event>
<event handle="_a5af0eb6abd74c3d7fc" change="1284030605" id="E3415">
<type>Death</type>
<dateval val="1642-01" type="about"/>
<description>Death of Abbott, Frances</description>
</event>
<event handle="_a5af0eb6add73de72aa" change="1284030598" id="E0014">
<type>Birth</type>
<dateval val="1520" type="about"/>
@ -17897,11 +17902,6 @@
<type>Death</type>
<dateval val="1850" type="about" quality="estimated"/>
</event>
<event handle="_a5af0eb6abd74c3d7fc" change="1284030605" id="E3415">
<type>Death</type>
<dateval val="1642-01" type="about"/>
<description>Death of Abbott, Frances</description>
</event>
</events>
<people home="_GNUJQCL9MD64AM56OH">
<person handle="_004KQCGYT27EEPQHK" change="1185438865" id="I0552">
@ -20260,7 +20260,7 @@
<parentin hlink="_HQ8KQCT2UX4S9I0E26"/>
<citationref hlink="_c140d24b31f74169170"/>
</person>
<person handle="_3RFKQCNKMX9HVLNSLW" change="1185438865" id="I1116">
<person handle="_3RFKQCNKMX9HVLNSLW" change="1431174900" id="I1116">
<gender>F</gender>
<name type="Birth Name">
<surname>Garner</surname>
@ -22104,7 +22104,7 @@
<parentin hlink="_JT4KQC83ZKPOLC0UEJ"/>
<citationref hlink="_c140d24fa2503a14583"/>
</person>
<person handle="_6TFKQCUTO94WB2NHN" change="1185438865" id="I1119">
<person handle="_6TFKQCUTO94WB2NHN" change="1431174900" id="I1119">
<gender>F</gender>
<name type="Birth Name">
<first>Zelpha Josephine</first>
@ -23913,7 +23913,7 @@
<parentin hlink="_1RUJQCCL9MVRYLMTBO"/>
<citationref hlink="_c140d254dcc234394a3"/>
</person>
<person handle="_9QFKQC54ET79K2SD57" change="1185438865" id="I1115">
<person handle="_9QFKQC54ET79K2SD57" change="1431174900" id="I1115">
<gender>F</gender>
<name type="Birth Name">
<first>Mary M.</first>
@ -24600,7 +24600,7 @@
<parentin hlink="_4W1KQCYZD6N5M576RA"/>
<citationref hlink="_c140d2566d57b164cf5"/>
</person>
<person handle="_AWFKQCJELLUWDY2PD3" change="1284030919" id="I1123">
<person handle="_AWFKQCJELLUWDY2PD3" change="1431174900" id="I1123">
<gender>M</gender>
<name type="Birth Name">
<first>Robert F.</first>
@ -27182,7 +27182,7 @@
<parentin hlink="_0Q3KQCBZ4421A3L5B4"/>
<citationref hlink="_c140d25c5be3120050a"/>
</person>
<person handle="_EPFKQCETTDTEL3PYIR" change="1185438865" id="I1114">
<person handle="_EPFKQCETTDTEL3PYIR" change="1431174900" id="I1114">
<gender>F</gender>
<name type="Birth Name">
<first>Mary J.</first>
@ -28226,7 +28226,7 @@
<parentin hlink="_BWAKQCZLIWDX9ZEFED"/>
<citationref hlink="_c140d25eec45aabbd80"/>
</person>
<person handle="_GNUJQCL9MD64AM56OH" change="1328027440" id="I0044">
<person handle="_GNUJQCL9MD64AM56OH" change="1431174904" id="I0044">
<gender>M</gender>
<name type="Birth Name">
<first>Lewis Anderson</first>
@ -28454,7 +28454,7 @@
<childof hlink="_05XJQC935HU62H3KL4"/>
<citationref hlink="_c140d25f5c448b251ca"/>
</person>
<person handle="_GYFKQCPH8Q0JDN94GR" change="1185438865" id="I1126">
<person handle="_GYFKQCPH8Q0JDN94GR" change="1431174900" id="I1126">
<gender>F</gender>
<name type="Birth Name">
<first>Anetta</first>
@ -32105,7 +32105,7 @@
<parentin hlink="_ZA6KQC27P0I8E2JZUC"/>
<citationref hlink="_c140d2677c105a1b132"/>
</person>
<person handle="_MUFKQCMXUJ07MCDUNI" change="1185438865" id="I1121">
<person handle="_MUFKQCMXUJ07MCDUNI" change="1431174900" id="I1121">
<gender>F</gender>
<name type="Birth Name">
<first>Iola Elizabeth Betty</first>
@ -33279,7 +33279,7 @@
<parentin hlink="_9SEKQCAAWRUCIO7A0M"/>
<citationref hlink="_c140d269f4c7c13bf87"/>
</person>
<person handle="_ORFKQC4KLWEGTGR19L" change="1185438865" id="I1117">
<person handle="_ORFKQC4KLWEGTGR19L" change="1431174900" id="I1117">
<gender>F</gender>
<name type="Birth Name">
<first>Rebecca Catharine</first>
@ -33963,7 +33963,7 @@
<parentin hlink="_IXDKQCOYLEMDKWJZPC"/>
<citationref hlink="_c140d26b98d33ec7f15"/>
</person>
<person handle="_PXFKQCXEHJX3W1Q1IV" change="1185438865" id="I1125">
<person handle="_PXFKQCXEHJX3W1Q1IV" change="1431174900" id="I1125">
<gender>F</gender>
<name type="Birth Name">
<first>Emma A.</first>
@ -35695,7 +35695,7 @@
<parentin hlink="_FP4KQCQQX8O84KK3IF"/>
<citationref hlink="_c140d27142a05b2d019"/>
</person>
<person handle="_SOFKQCBYAO18OWC0CS" change="1185438865" id="I1113">
<person handle="_SOFKQCBYAO18OWC0CS" change="1431174900" id="I1113">
<gender>F</gender>
<name type="Birth Name">
<first>Phebe</first>
@ -37068,7 +37068,7 @@
<parentin hlink="_7ZWJQC8ZR4WJZE09RW"/>
<citationref hlink="_c140d276c1802ec5ac3"/>
</person>
<person handle="_UZFKQCIHVT44DC9KGH" change="1185438865" id="I1128">
<person handle="_UZFKQCIHVT44DC9KGH" change="1431174900" id="I1128">
<gender>F</gender>
<name type="Birth Name">
<first>Antoinette</first>
@ -42060,12 +42060,12 @@
<childref hlink="_GH0KQCGPLF5J17PELU"/>
<citationref hlink="_c140d286d0e2f46fb29"/>
</family>
<family handle="_8OUJQCUVZ0XML7BQLF" change="1185438865" id="F0018">
<family handle="_8OUJQCUVZ0XML7BQLF" change="1431174900" id="F0018">
<rel type="Married"/>
<father hlink="_35WJQC1B7T7NPV8OLV"/>
<mother hlink="_46WJQCIOLQ0KOX2XCC"/>
<eventref hlink="_a5af0ed602318310d6d" role="Family"/>
<childref hlink="_GNUJQCL9MD64AM56OH"/>
<childref hlink="_GNUJQCL9MD64AM56OH" mrel="Custom relationship to mother" frel="Custom relationship to father"/>
<childref hlink="_SOFKQCBYAO18OWC0CS"/>
<childref hlink="_EPFKQCETTDTEL3PYIR"/>
<childref hlink="_9QFKQC54ET79K2SD57"/>
@ -63928,6 +63928,94 @@ page 26 Repository:Address</text>
<range start="0" end="705"/>
</style>
</note>
<note handle="_d0436bba4ec328d3b631259a4ee" change="1431184305" id="_header1" type="General">
<text>Title for the example pages</text>
<style name="fontcolor" value="#ef2929">
<range start="0" end="27"/>
</style>
<style name="underline">
<range start="0" end="27"/>
</style>
<style name="fontface" value="Serif">
<range start="0" end="27"/>
</style>
<style name="bold">
<range start="0" end="27"/>
</style>
<style name="fontsize" value="8">
<range start="0" end="27"/>
</style>
</note>
<note handle="_d0436bcc69d6bba278bff5bc7db" change="1431184300" id="_footer1" type="General">
<text>Footer: exported by __GRAMPS_HOMEPAGE__ on __EXPORT_DATE__</text>
</note>
<note handle="_d0436be64ac277b615b79b34e72" change="1431211661" id="_custom1" type="General">
<text>Export date: __EXPORT_DATE__
GRAMPS homepage: __GRAMPS_HOMEPAGE__
GRAMPS version: __GRAMPS_VERSION__
Number of families: __NB_FAMILIES__
Number of persons: __NB_INDIVIDUALS__
Number of media objects: __NB_MEDIA__
Number of sources: __NB_SOURCES__
Number of repositories: __NB_REPOSITORIES__
Number of places: __NB_PLACES__
Search form:
__SEARCH_FORM__
Test link person: Garner von Zieliński, Lewis Anderson Sr
Test link family: Family of Warner, Allen Carl and Garner, Rita Marie
Test link source: World of the Wierd
Test link media: 1897_expeditionsmannschaft_rio_a
Test link place: Warren-Farmington Hills-Troy, MI
Test internet link: blog.codinghorror.com
Test relative path link: relative file path to &quot;archive.zip&quot;
Test relative path link: relative file path to &quot;archive.tgz&quot;
Thumbnail for &quot;1897_expeditionsmannschaft_rio_a&quot;:
__THUMB_O0010__
Image &quot;AntoineClaudet&quot;:
__MEDIA_O0011__
Thumbnail for &quot;1897_expeditionsmannschaft_rio_a&quot; with link:
__THUMB_O0010__
Image &quot;AntoineClaudet&quot; with link:
__MEDIA_O0011__
Wrong media ID:
__MEDIA_wrong id__</text>
<style name="link" value="relative://relative.archive.zip">
<range start="663" end="686"/>
</style>
<style name="link" value="gramps://Media/handle/238CGQ939HG18SS5MG">
<range start="952" end="967"/>
</style>
<style name="link" value="gramps://Media/handle/238CGQ939HG18SS5MG">
<range start="520" end="535"/>
</style>
<style name="link" value="gramps://Family/handle/48TJQCGNNIR5SJRCAK">
<range start="413" end="429"/>
</style>
<style name="link" value="gramps://Person/handle/GNUJQCL9MD64AM56OH">
<range start="355" end="371"/>
</style>
<style name="link" value="http://blog.codinghorror.com/">
<range start="621" end="639"/>
</style>
<style name="link" value="gramps://Source/handle/VUBKMQTA2XZG1V6QP8">
<range start="483" end="499"/>
</style>
<style name="link" value="gramps://Place/handle/3WTJQCB9F2MX9W98VP">
<range start="570" end="585"/>
</style>
<style name="link" value="gramps://Media/handle/Y3ARGQWE088EQRTTDH">
<range start="1002" end="1017"/>
</style>
<style name="link" value="relative://relative.archive.tgz">
<range start="724" end="747"/>
</style>
</note>
</notes>
<bookmarks>
<bookmark target="person" hlink="_AWFKQCJELLUWDY2PD3"/>

View File

@ -339,6 +339,79 @@ class MissingMediaDialog(object):
self.top)
return True
class MultiSelectDialog(object):
def __init__(self, msg1_func, msg2_func, items, lookup,
cancel_func=None, no_func=None, yes_func=None,
parent=None):
"""
"""
self.xml = Glade(toplevel='multiselectdialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.msg1_func = msg1_func
self.msg2_func = msg2_func
self.items = items
self.lookup = lookup
self.cancel_func = cancel_func
self.no_func = no_func
self.yes_func = yes_func
label1 = self.xml.get_object('label6')
label2 = self.xml.get_object('label5')
check_button = self.xml.get_object('apply_to_rest')
if parent:
self.top.set_transient_for(parent)
self.top.connect('delete_event', self.warn)
default_action = 0
for selected in items:
item = self.lookup(selected)
if default_action == 0:
msg1 = self.msg1_func(item)
msg2 = self.msg2_func(item)
self.top.set_title("%s - Gramps" % msg1)
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2.set_text(msg2)
label2.set_use_markup(True)
self.top.show()
# Need some magic here, because an attempt to close the dialog
# with the X button not only emits the 'delete_event' signal
# but also exits with the RESPONSE_DELETE_EVENT
response = Gtk.ResponseType.DELETE_EVENT
while response == Gtk.ResponseType.DELETE_EVENT:
response = self.top.run()
if check_button.get_active():
default_action = response
else:
response = default_action
### Now do it
if response == 1: # Cancel
if self.cancel_func:
self.cancel_func(item)
break
elif response == 2: # No
if self.no_func:
self.no_func(item)
elif response == 3: # Yes
if self.yes_func:
self.yes_func(item)
self.top.destroy()
def warn(self, obj, obj2):
WarningDialog(
_("Attempt to force closing the dialog"),
_("Please do not force closing this important dialog.\n"
"Instead select one of the available options"),
self.top)
return True
class MessageHideDialog(object):
def __init__(self, title, message, key, parent=None):

View File

@ -397,6 +397,169 @@
<action-widget response="3">button11</action-widget>
</action-widgets>
</object>
<object class="GtkDialog" id="multiselectdialog">
<property name="can_focus">False</property>
<property name="default_width">600</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox143">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="hbuttonbox50">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button183">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Cancel the rest of the operations</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button184">
<property name="label" translatable="yes">_No</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Do not apply the operation to this item</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button185">
<property name="label" translatable="yes">_Yes</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Apply the operation to this item</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="table82">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">24</property>
<property name="margin_bottom">24</property>
<property name="hexpand">True</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
<property name="ellipsize">start</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="pixel_size">48</property>
<property name="icon_name">dialog-warning</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="hexpand">True</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="apply_to_rest">
<property name="label" translatable="yes">_Use this answer for the rest of the items</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">If you check this button, your next answer will apply to the rest of the selected items</property>
<property name="halign">center</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="1">button183</action-widget>
<action-widget response="2">button184</action-widget>
<action-widget response="3">button185</action-widget>
</action-widgets>
</object>
<object class="GtkDialog" id="optiondialog">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>

View File

@ -168,7 +168,7 @@ class DocReportDialog(ReportDialog):
self.make_doc_menu(self.options.handler.get_format_name())
self.format_menu.connect('changed', self.doc_type_changed)
label = Gtk.Label(label="%s:" % _("Output Format"))
label.set_set_halign(Gtk.Align.START)
label.set_halign(Gtk.Align.START)
self.grid.attach(label, 1, self.row, 1, 1)
self.format_menu.set_hexpand(True)
self.grid.attach(self.format_menu, 2, self.row, 2, 1)
@ -214,7 +214,7 @@ class DocReportDialog(ReportDialog):
self.html_grid.set_border_width(6)
label = Gtk.Label(label="%s:" % _("CSS file"))
label.set_set_halign(Gtk.Align.START)
label.set_halign(Gtk.Align.START)
self.html_grid.attach(label, 1, 1, 1, 1)
self.css_combo = Gtk.ComboBoxText()

View File

@ -537,11 +537,11 @@ class ListView(NavigationView):
prompt = True
if len(self.selected_handles()) > 1:
q = QuestionDialog2(
_("Confirm every deletion?"),
_("Multiple Selection Delete"),
_("More than one item has been selected for deletion. "
"Ask before deleting each one?"),
_("No"),
_("Yes"))
"Select the option indicating how to delete the items:"),
_("Delete All"),
_("Confirm Each Delete"))
prompt = not q.run()
if not prompt:

View File

@ -51,7 +51,7 @@ from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.actiongroup import ActionGroup
from gramps.gen.utils.string import data_recover_msg
from gramps.gen.display.name import displayer as name_displayer
from gramps.gui.dialog import ErrorDialog, QuestionDialog
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.config import config
@ -286,20 +286,43 @@ class BasePersonView(ListView):
"""
Remove a person from the database.
"""
for sel in self.selected_handles():
person = self.dbstate.db.get_person_from_handle(sel)
self.active_person = person
name = name_displayer.display(person)
handles = self.selected_handles()
if len(handles) == 1:
person = self._lookup_person(handles[0])
msg1 = self._message1_format(person)
msg2 = self._message2_format(person)
msg2 = "%s %s" % (msg2, data_recover_msg)
# This gets person to delete deom self.active_person:
QuestionDialog(msg1,
msg2,
_('_Delete Person'),
self.delete_person_response)
else:
# Ask to delete; option to cancel, delete rest
# This gets person to delete from parameter
MultiSelectDialog(self._message1_format,
self._message2_format,
handles,
self._lookup_person,
yes_func=self.delete_person_response) # Yes
msg = _('Deleting the person will remove the person '
'from the database.')
msg = "%s %s" % (msg, data_recover_msg)
QuestionDialog(_('Delete %s?') % name,
msg,
_('_Delete Person'),
self.delete_person_response)
def _message1_format(self, person):
return _('Delete %s?') % (name_displayer.display(person) +
(" [%s]" % person.gramps_id))
def delete_person_response(self):
def _message2_format(self, person):
return _('Deleting the person will remove the person '
'from the database.')
def _lookup_person(self, handle):
"""
Get the next person from handle.
"""
person = self.dbstate.db.get_person_from_handle(handle)
self.active_person = person
return person
def delete_person_response(self, person=None):
"""
Deletes the person from the database.
"""

View File

@ -229,18 +229,55 @@ class FamilyView(ListView):
pass
def remove(self, obj):
from gramps.gui.dialog import QuestionDialog2
"""
Method called when deleting a family from a family view.
"""
from gramps.gui.dialog import QuestionDialog, MultiSelectDialog
from gramps.gen.utils.string import data_recover_msg
msg = _('Deleting item will remove it from the database.')
msg = msg + '\n' + data_recover_msg
q = QuestionDialog2(_('Delete %s?') % _('family'), msg,
_('_Delete Item'), _('Cancel'))
if q.run():
self.uistate.set_busy_cursor(True)
list(map(self.dbstate.db.remove_family_relationships,
self.selected_handles()))
self.build_tree()
self.uistate.set_busy_cursor(False)
handles = self.selected_handles()
if len(handles) == 1:
family = self.dbstate.db.get_family_from_handle(handles[0])
msg1 = self._message1_format(family)
msg2 = self._message2_format(family)
msg2 = "%s %s" % (msg2, data_recover_msg)
QuestionDialog(msg1,
msg2,
_('_Delete Family'),
lambda: self.delete_family_response(family))
else:
MultiSelectDialog(self._message1_format,
self._message2_format,
handles,
self.dbstate.db.get_family_from_handle,
yes_func=self.delete_family_response)
def _message1_format(self, family):
"""
Header format for remove dialogs.
"""
return _('Delete %s?') % (_('family') +
(" [%s]" % family.gramps_id))
def _message2_format(self, family):
"""
Detailed message format for the remove dialogs.
"""
return _('Deleting item will remove it from the database.')
def delete_family_response(self, family):
"""
Deletes the family from the database. Callback to remove
dialogs.
"""
from gramps.gen.db import DbTxn
# set the busy cursor, so the user knows that we are working
self.uistate.set_busy_cursor(True)
# create the transaction
with DbTxn('', self.dbstate.db) as trans:
gramps_id = family.gramps_id
self.dbstate.db.remove_family_relationships(family.handle, trans)
trans.set_description(_("Family [%s]") % gramps_id)
self.uistate.set_busy_cursor(False)
def edit(self, obj):
for handle in self.selected_handles():

View File

@ -511,8 +511,8 @@ def format_date(date):
cal = date.get_calendar()
mod = date.get_modifier()
quality = date.get_quality()
if quality in libgedcom.DATE_QUALITY:
qual_text = libgedcom.DATE_QUALITY[quality] + " "
if quality in DATE_QUALITY:
qual_text = DATE_QUALITY[quality] + " "
else:
qual_text = ""
if mod == Date.MOD_SPAN: