diff --git a/gramps/gen/config.py b/gramps/gen/config.py index f199c5700..dd4885d66 100644 --- a/gramps/gen/config.py +++ b/gramps/gen/config.py @@ -246,6 +246,8 @@ register('interface.person-sel-height', 450) register('interface.person-sel-width', 600) register('interface.person-width', 750) register('interface.place-height', 450) +register('interface.place-name-height', 100) +register('interface.place-name-width', 450) register('interface.place-ref-height', 450) register('interface.place-ref-width', 600) register('interface.place-sel-height', 450) diff --git a/gramps/gen/db/upgrade.py b/gramps/gen/db/upgrade.py index e679eba3f..85ddd06da 100644 --- a/gramps/gen/db/upgrade.py +++ b/gramps/gen/db/upgrade.py @@ -144,7 +144,7 @@ def gramps_upgrade_17(self): placeref_list = [] type_num = 7 - level if name else 8 - new_place = new_place[:5] + [placeref_list, name, + new_place = new_place[:5] + [placeref_list, name, [], PlaceType(type_num).serialize(), zip_code] + \ new_place[6:12] + [[]] + new_place[12:] new_place = tuple(new_place) diff --git a/gramps/gen/lib/place.py b/gramps/gen/lib/place.py index b8aed5e58..587c1724a 100644 --- a/gramps/gen/lib/place.py +++ b/gramps/gen/lib/place.py @@ -73,6 +73,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): self.lat = source.lat self.title = source.title self.name = source.name + self.alt_names = source.alt_names self.placeref_list = list(map(PlaceRef, source.placeref_list)) self.place_type = source.place_type self.code = source.code @@ -82,6 +83,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): self.lat = "" self.title = "" self.name = "" + self.alt_names = [] self.placeref_list = [] self.place_type = PlaceType() self.code = "" @@ -107,7 +109,8 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): """ return (self.handle, self.gramps_id, self.title, self.long, self.lat, [pr.serialize() for pr in self.placeref_list], - self.name, self.place_type.serialize(), self.code, + self.name, self.alt_names, + self.place_type.serialize(), self.code, [al.serialize() for al in self.alt_loc], UrlBase.serialize(self), MediaBase.serialize(self), @@ -143,6 +146,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): "lat": self.lat, "placeref_list": [pr.to_struct() for pr in self.placeref_list], "name": self.name, + "alt_names": self.alt_names, "place_type": self.place_type.to_struct(), "code": self.code, "alt_loc": [al.to_struct() for al in self.alt_loc], @@ -169,6 +173,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): struct.get("lat", default.lat), [PlaceRef.from_struct(pr) for pr in struct.get("placeref_list", default.placeref_list)], struct.get("name", default.name), + struct.get("alt_names", default.alt_names), PlaceType.from_struct(struct.get("place_type", {})), struct.get("code", default.code), [Location.from_struct(al) for al in struct.get("alt_loc", default.alt_loc)], @@ -190,7 +195,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): :type data: tuple """ (self.handle, self.gramps_id, self.title, self.long, self.lat, - placeref_list, self.name, the_type, self.code, + placeref_list, self.name, self.alt_names, the_type, self.code, alt_loc, urls, media_list, citation_list, note_list, self.change, tag_list, self.private) = data @@ -274,6 +279,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): """ self._merge_privacy(acquisition) self._merge_locations(acquisition) + self._merge_alt_names(acquisition) self._merge_media_list(acquisition) self._merge_url_list(acquisition) self._merge_note_list(acquisition) @@ -520,3 +526,18 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): break else: self.alt_loc.append(addendum) + + def _merge_alt_names(self, acquisition): + """ + Add the main and alternative names of acquisition to the alternative + names list. + + :param acquisition: instance to merge + :type acquisition: :class:'~.place.Place + """ + if acquisition.name not in self.alt_names: + self.alt_names.append(acquisition.name) + + for addendum in acquisition.alt_names: + if addendum not in self.alt_names: + self.alt_names.append(addendum) diff --git a/gramps/gui/editors/__init__.py b/gramps/gui/editors/__init__.py index e680c679f..dd28b6a67 100644 --- a/gramps/gui/editors/__init__.py +++ b/gramps/gui/editors/__init__.py @@ -39,6 +39,7 @@ from .editnote import EditNote, DeleteNoteQuery from .editperson import EditPerson from .editpersonref import EditPersonRef from .editplace import EditPlace, DeletePlaceQuery +from .editplacename import EditPlaceName from .editplaceref import EditPlaceRef from .editrepository import EditRepository, DeleteRepositoryQuery from .editreporef import EditRepoRef diff --git a/gramps/gui/editors/displaytabs/__init__.py b/gramps/gui/editors/displaytabs/__init__.py index 88cd4e609..7049ad2e1 100644 --- a/gramps/gui/editors/displaytabs/__init__.py +++ b/gramps/gui/editors/displaytabs/__init__.py @@ -37,6 +37,7 @@ from .childmodel import ChildModel from .grampstab import GrampsTab from .embeddedlist import EmbeddedList, TEXT_COL, MARKUP_COL, ICON_COL from .addrembedlist import AddrEmbedList +from .altnameembedlist import AltNameEmbedList from .attrembedlist import AttrEmbedList from .backreflist import BackRefList from .eventbackreflist import EventBackRefList diff --git a/gramps/gui/editors/displaytabs/altnameembedlist.py b/gramps/gui/editors/displaytabs/altnameembedlist.py new file mode 100644 index 000000000..649c55762 --- /dev/null +++ b/gramps/gui/editors/displaytabs/altnameembedlist.py @@ -0,0 +1,91 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2006 Donald N. Allingham +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +#------------------------------------------------------------------------- +# +# Python classes +# +#------------------------------------------------------------------------- +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext +from gi.repository import GObject + +#------------------------------------------------------------------------- +# +# Gramps classes +# +#------------------------------------------------------------------------- +from gramps.gen.errors import WindowActiveError +from .altnamemodel import AltNameModel +from .embeddedlist import EmbeddedList, TEXT_COL, MARKUP_COL, ICON_COL + +#------------------------------------------------------------------------- +# +# AltNameEmbedList +# +#------------------------------------------------------------------------- +class AltNameEmbedList(EmbeddedList): + + _HANDLE_COL = 0 + + #index = column in model. Value = + # (name, sortcol in model, width, markup/text, weigth_col + _column_names = [ + (_('Place Name'), 0, 250, TEXT_COL, -1, None), + ] + + def __init__(self, dbstate, uistate, track, data): + self.data = data + EmbeddedList.__init__(self, dbstate, uistate, track, + _('Alternative Names'), AltNameModel, + move_buttons=True) + + def get_data(self): + return self.data + + def column_order(self): + return ((1, 0),) + + def add_button_clicked(self, obj): + try: + from .. import EditPlaceName + EditPlaceName(self.dbstate, self.uistate, self.track, + self.get_data(), -1, self.add_callback) + except WindowActiveError: + pass + + def add_callback(self, place_name): + data = self.get_data() + self.rebuild() + GObject.idle_add(self.tree.scroll_to_cell, len(data) - 1) + + def edit_button_clicked(self, obj): + place_name = self.get_selected() + if place_name: + try: + from .. import EditPlaceName + data = self.get_data() + EditPlaceName(self.dbstate, self.uistate, self.track, + data, data.index(place_name), self.edit_callback) + except WindowActiveError: + pass + + def edit_callback(self, place_name): + self.rebuild() diff --git a/gramps/gui/editors/displaytabs/altnamemodel.py b/gramps/gui/editors/displaytabs/altnamemodel.py new file mode 100644 index 000000000..51b8b8518 --- /dev/null +++ b/gramps/gui/editors/displaytabs/altnamemodel.py @@ -0,0 +1,46 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2014 Nick Hall +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +#------------------------------------------------------------------------- +# +# GTK libraries +# +#------------------------------------------------------------------------- +from gi.repository import Gtk + +#------------------------------------------------------------------------- +# +# Gramps classes +# +#------------------------------------------------------------------------- + + +#------------------------------------------------------------------------- +# +# AltNameModel +# +#------------------------------------------------------------------------- +class AltNameModel(Gtk.ListStore): + + def __init__(self, place_name_list, db): + Gtk.ListStore.__init__(self, str) + self.db = db + for place_name in place_name_list: + self.append(row=[place_name]) diff --git a/gramps/gui/editors/editplace.py b/gramps/gui/editors/editplace.py index 56f45281d..de3e8d034 100644 --- a/gramps/gui/editors/editplace.py +++ b/gramps/gui/editors/editplace.py @@ -48,8 +48,9 @@ from gi.repository import Gtk from gramps.gen.lib import NoteType, Place from gramps.gen.db import DbTxn from .editprimary import EditPrimary -from .displaytabs import (PlaceRefEmbedList, LocationEmbedList, CitationEmbedList, - GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList) +from .displaytabs import (PlaceRefEmbedList, AltNameEmbedList, + LocationEmbedList, CitationEmbedList, + GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList) from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredTagList, MonitoredDataType) from gramps.gen.errors import ValidationError @@ -179,6 +180,13 @@ class EditPlace(EditPrimary): self._add_tab(notebook, self.placeref_list) self.track_ref_for_deletion("placeref_list") + self.alt_name_list = AltNameEmbedList(self.dbstate, + self.uistate, + self.track, + self.obj.alt_names) + self._add_tab(notebook, self.alt_name_list) + self.track_ref_for_deletion("alt_name_list") + if len(self.obj.alt_loc) > 0: self.loc_list = LocationEmbedList(self.dbstate, self.uistate, diff --git a/gramps/gui/editors/editplacename.py b/gramps/gui/editors/editplacename.py new file mode 100644 index 000000000..056fa710a --- /dev/null +++ b/gramps/gui/editors/editplacename.py @@ -0,0 +1,103 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2006 Donald N. Allingham +# Copyright (C) 2014 Nick Hall +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +#------------------------------------------------------------------------- +# +# GTK/Gnome modules +# +#------------------------------------------------------------------------- +from gi.repository import Gtk + +#------------------------------------------------------------------------- +# +# Gramps modules +# +#------------------------------------------------------------------------- +from ..managedwindow import ManagedWindow +from ..dialog import ErrorDialog +from ..display import display_help +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------- +# +# EditPlaceName class +# +#------------------------------------------------------------------------- +class EditPlaceName(ManagedWindow): + + def __init__(self, dbstate, uistate, track, data, index, callback): + ManagedWindow.__init__(self, uistate, track, self.__class__) + + self.data = data + self.index = index + self.callback = callback + + self.width_key = 'interface.place-name-width' + self.height_key = 'interface.place-name-height' + + window = Gtk.Dialog('', uistate.window, + Gtk.DialogFlags.DESTROY_WITH_PARENT, None) + + self.cancel_button = window.add_button(Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL) + self.ok_button = window.add_button(Gtk.STOCK_OK, + Gtk.ResponseType.ACCEPT) + self.help_button = window.add_button(Gtk.STOCK_HELP, + Gtk.ResponseType.HELP) + + window.connect('response', self.response) + self.set_window(window, None, _('Place Name Editor')) + + hbox = Gtk.HBox() + label = Gtk.Label(_('Place Name:')) + self.entry = Gtk.Entry() + if index >= 0: + self.entry.set_text(data[index]) + hbox.pack_start(label, False, False, 4) + hbox.pack_start(self.entry, True, True, 4) + hbox.show_all() + window.vbox.pack_start(hbox, False, False, 4) + + self._set_size() + self.show() + + def response(self, obj, response_id): + if response_id == Gtk.ResponseType.CANCEL: + self.close() + if response_id == Gtk.ResponseType.ACCEPT: + self.save() + if response_id == Gtk.ResponseType.HELP: + display_help('', '') + + def save(self, *obj): + place_name = self.entry.get_text() + if not place_name: + ErrorDialog(_("Cannot save place name"), + _("The place name cannot be empty")) + return + if self.index >= 0: + self.data[self.index] = place_name + else: + self.data.append(place_name) + if self.callback: + self.callback(place_name) + self.close() diff --git a/gramps/gui/views/treemodels/placemodel.py b/gramps/gui/views/treemodels/placemodel.py index d34de8f27..47ba60e2d 100644 --- a/gramps/gui/views/treemodels/placemodel.py +++ b/gramps/gui/views/treemodels/placemodel.py @@ -158,23 +158,23 @@ class PlaceBaseModel(object): return cuni(data[1]) def column_type(self, data): - return str(PlaceType(data[7])) + return str(PlaceType(data[8])) def column_code(self, data): - return cuni(data[8]) + return cuni(data[9]) def column_private(self, data): - if data[16]: + if data[17]: return 'gramps-lock' else: # There is a problem returning None here. return '' def sort_change(self, data): - return "%012x" % data[14] + return "%012x" % data[15] def column_change(self, data): - return format_time(data[14]) + return format_time(data[15]) def get_tag_name(self, tag_handle): """ @@ -188,7 +188,7 @@ class PlaceBaseModel(object): """ tag_color = "#000000000000" tag_priority = None - for handle in data[15]: + for handle in data[16]: tag = self.db.get_tag_from_handle(handle) if tag: this_priority = tag.get_priority() @@ -201,7 +201,7 @@ class PlaceBaseModel(object): """ Return the sorted list of tags. """ - tag_list = list(map(self.get_tag_name, data[15])) + tag_list = list(map(self.get_tag_name, data[16])) return ', '.join(sorted(tag_list, key=glocale.sort_key)) #------------------------------------------------------------------------- diff --git a/po/POTFILES.in b/po/POTFILES.in index f6855438b..bf6603a55 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -344,6 +344,7 @@ gramps/gui/dialog.py gramps/gui/displaystate.py gramps/gui/editors/addmedia.py gramps/gui/editors/displaytabs/addrembedlist.py +gramps/gui/editors/displaytabs/altnameembedlist.py gramps/gui/editors/displaytabs/attrembedlist.py gramps/gui/editors/displaytabs/backreflist.py gramps/gui/editors/displaytabs/backrefmodel.py @@ -384,6 +385,7 @@ gramps/gui/editors/editnote.py gramps/gui/editors/editperson.py gramps/gui/editors/editpersonref.py gramps/gui/editors/editplace.py +gramps/gui/editors/editplacename.py gramps/gui/editors/editplaceref.py gramps/gui/editors/editprimary.py gramps/gui/editors/editreporef.py diff --git a/po/POTFILES.skip b/po/POTFILES.skip index fc1957df0..967f5c7e0 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -287,6 +287,7 @@ gramps/gui/editors/editsecondary.py # gramps/gui/editors/displaytabs/__init__.py gramps/gui/editors/displaytabs/addressmodel.py +gramps/gui/editors/displaytabs/altnamemodel.py gramps/gui/editors/displaytabs/attrmodel.py gramps/gui/editors/displaytabs/childmodel.py gramps/gui/editors/displaytabs/citationbackreflist.py