1#
2# Gramps - a GTK+/GNOME based genealogy program
3#
4# Copyright (C) 2000-2006  Donald N. Allingham
5# Copyright (C) 2008       Brian G. Matherly
6# Copyright (C) 2010       Jakim Friant
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22
23"""Database Processing/Rename Event Types"""
24
25#-------------------------------------------------------------------------
26#
27# GNOME modules
28#
29#-------------------------------------------------------------------------
30from gi.repository import Gtk
31from gi.repository import GObject
32
33#------------------------------------------------------------------------
34#
35# Gramps modules
36#
37#------------------------------------------------------------------------
38from gramps.gen.const import GRAMPS_LOCALE as glocale
39_ = glocale.translation.gettext
40ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
41from gramps.gui.utils import ProgressMeter
42from gramps.gui.managedwindow import ManagedWindow
43from gramps.gen.lib import EventType
44from gramps.gen.db import DbTxn
45from gramps.gui.plug import tool
46from gramps.gui.glade import Glade
47
48#-------------------------------------------------------------------------
49#
50# ChangeTypes class
51#
52#-------------------------------------------------------------------------
53class ChangeTypes(tool.BatchTool, ManagedWindow):
54
55    def __init__(self, dbstate, user, options_class, name, callback=None):
56        uistate = user.uistate
57        self.user = user
58        self.dbstate = dbstate
59
60        tool.BatchTool.__init__(self, dbstate, user, options_class, name)
61        if self.fail:
62            return
63
64        if uistate:
65            self.title = _('Change Event Types')
66            ManagedWindow.__init__(self,uistate,[],
67                                                 self.__class__)
68            self.init_gui()
69        else:
70            self.run_tool()
71
72    def init_gui(self):
73        # Draw dialog and make it handle everything
74
75        self.glade = Glade()
76
77        self.auto1 = self.glade.get_object("original")
78        self.auto2 = self.glade.get_object("new")
79
80        # Need to display localized event names
81        etype = EventType()
82        custom_events = self.dbstate.db.get_event_types()
83        event_names = sorted(etype.get_standard_names() + custom_events,
84                             key=glocale.sort_key)
85
86        self.fill_combo(self.auto1,event_names)
87        self.fill_combo(self.auto2,event_names)
88
89        etype.set_from_xml_str(self.options.handler.options_dict['fromtype'])
90        self.auto1.get_child().set_text(str(etype))
91
92        etype.set_from_xml_str(self.options.handler.options_dict['totype'])
93        self.auto2.get_child().set_text(str(etype))
94
95        window = self.glade.toplevel
96        self.set_window(window,self.glade.get_object('title'),self.title)
97        self.setup_configs('interface.changetypes', 640, 260)
98
99        self.glade.connect_signals({
100            "on_close_clicked"  : self.close,
101            "on_apply_clicked"  : self.on_apply_clicked,
102            "on_delete_event"   : self.close,
103            })
104
105        self.show()
106
107    def build_menu_names(self, obj):
108        return (self.title,None)
109
110    def run_tool(self, parent_window = None):
111        # Run tool and return results
112        # These are English names, no conversion needed
113        fromtype = self.options.handler.options_dict['fromtype']
114        totype = self.options.handler.options_dict['totype']
115
116        modified = 0
117
118        with DbTxn(_('Change types'), self.db, batch=True) as self.trans:
119            self.db.disable_signals()
120            with self.user.progress(
121                    _('Analyzing Events'), '',
122                    self.db.get_number_of_events()) as step:
123                for event_handle in self.db.get_event_handles():
124                    event = self.db.get_event_from_handle(event_handle)
125                    if event.get_type().xml_str() == fromtype:
126                        event.type.set_from_xml_str(totype)
127                        modified += 1
128                        self.db.commit_event(event,self.trans)
129                        step()
130        self.db.enable_signals()
131        self.db.request_rebuild()
132
133        if modified == 0:
134            msg = _("No event record was modified.")
135        else:
136            # translators: leave all/any {...} untranslated
137            msg = ngettext("{number_of} event record was modified.",
138                           "{number_of} event records were modified.", modified
139                          ).format(number_of=modified)
140
141        self.user.info(_('Change types'), msg, parent=parent_window)
142        return (bool(modified),msg)
143
144    def on_apply_clicked(self, obj):
145        # Need to store English names for later comparison
146        the_type = EventType()
147
148        the_type.set(self.auto1.get_child().get_text())
149        self.options.handler.options_dict['fromtype'] = the_type.xml_str()
150
151        the_type.set(self.auto2.get_child().get_text())
152        self.options.handler.options_dict['totype'] = the_type.xml_str()
153
154        self.run_tool(self.parent_window)
155
156        # Save options
157        self.options.handler.save_options()
158
159        self.close()
160
161    def fill_combo(self, combo, data_list):
162        """
163        Fill a combo box with completion data
164        """
165        store = Gtk.ListStore(GObject.TYPE_STRING)
166
167        for data in data_list:
168            if data:
169                store.append(row=[data])
170
171        combo.set_popup_fixed_width(False)
172        combo.set_wrap_width(4)
173        combo.set_model(store)
174        combo.set_entry_text_column(0)
175        completion = Gtk.EntryCompletion()
176        completion.set_model(store)
177        completion.set_minimum_key_length(1)
178        completion.set_text_column(0)
179        combo.get_child().set_completion(completion)
180
181#------------------------------------------------------------------------
182#
183#
184#
185#------------------------------------------------------------------------
186class ChangeTypesOptions(tool.ToolOptions):
187    """
188    Defines options and provides handling interface.
189    """
190
191    def __init__(self, name,person_id=None):
192        tool.ToolOptions.__init__(self, name,person_id)
193
194        # Options specific for this report
195        self.options_dict = {
196            'fromtype'   : '',
197            'totype'     : '',
198        }
199        self.options_help = {
200            'fromtype'   : ("=str","Type of events to replace",
201                            "Event type string"),
202            'totype'     : ("=str","New type replacing the old one",
203                            "Event type string"),
204        }
205