1# Gramps - a GTK+/GNOME based genealogy program 2# 3# Copyright (C) 2001-2006 Donald N. Allingham 4# Copyright (C) 2008 Gary Burton 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19# 20 21""" 22Repository View 23""" 24 25#------------------------------------------------------------------------- 26# 27# GTK/Gnome modules 28# 29#------------------------------------------------------------------------- 30from gi.repository import Gtk 31 32#------------------------------------------------------------------------- 33# 34# gramps modules 35# 36#------------------------------------------------------------------------- 37from gramps.gen.lib import Repository 38from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON 39from gramps.gui.views.treemodels import RepositoryModel 40from gramps.gui.views.bookmarks import RepoBookmarks 41from gramps.gen.errors import WindowActiveError 42from gramps.gen.config import config 43from gramps.gui.editors import EditRepository, DeleteRepositoryQuery 44from gramps.gui.ddtargets import DdTargets 45from gramps.gui.dialog import ErrorDialog 46from gramps.gui.filters.sidebar import RepoSidebarFilter 47from gramps.gui.merge import MergeRepository 48from gramps.gen.plug import CATEGORY_QR_REPOSITORY 49 50#------------------------------------------------------------------------- 51# 52# internationalization 53# 54#------------------------------------------------------------------------- 55from gramps.gen.const import GRAMPS_LOCALE as glocale 56_ = glocale.translation.sgettext 57 58 59#------------------------------------------------------------------------- 60# 61# RepositoryView 62# 63#------------------------------------------------------------------------- 64class RepositoryView(ListView): 65 """ repository listview class 66 """ 67 COL_NAME = 0 68 COL_ID = 1 69 COL_TYPE = 2 70 COL_URL = 3 71 COL_STREET = 4 72 COL_LOCALITY = 5 73 COL_CITY = 6 74 COL_STATE = 7 75 COL_COUNTRY = 8 76 COL_ZIP = 9 77 COL_EMAIL = 10 78 COL_SURL = 11 79 COL_PRIV = 12 80 COL_TAGS = 13 81 COL_CHAN = 14 82 83 # column definitions 84 COLUMNS = [ 85 (_('Name'), TEXT, None), 86 (_('ID'), TEXT, None), 87 (_('Type'), TEXT, None), 88 (_('Home URL'), TEXT, None), 89 (_('Street'), TEXT, None), 90 (_('Locality'), TEXT, None), 91 (_('City'), TEXT, None), 92 (_('State/County'), TEXT, None), 93 (_('Country'), TEXT, None), 94 (_('ZIP/Postal Code'), TEXT, None), 95 (_('Email'), TEXT, None), 96 (_('Search URL'), TEXT, None), 97 (_('Private'), ICON, 'gramps-lock'), 98 (_('Tags'), TEXT, None), 99 (_('Last Changed'), TEXT, None), 100 ] 101 # default setting with visible columns, order of the col, and their size 102 CONFIGSETTINGS = ( 103 ('columns.visible', [COL_NAME, COL_ID, COL_TYPE, COL_URL, COL_STREET, 104 ]), 105 ('columns.rank', [COL_NAME, COL_ID, COL_TYPE, COL_URL, COL_STREET, 106 COL_LOCALITY, COL_CITY, COL_STATE, COL_COUNTRY, 107 COL_ZIP, COL_EMAIL, COL_SURL, COL_PRIV, COL_TAGS, 108 COL_CHAN]), 109 ('columns.size', [200, 75, 100, 250, 100, 100, 100, 100, 100, 110 100, 100, 100, 40, 100, 100]) 111 ) 112 ADD_MSG = _("Add a new repository") 113 EDIT_MSG = _("Edit the selected repository") 114 DEL_MSG = _("Delete the selected repository") 115 MERGE_MSG = _("Merge the selected repositories") 116 FILTER_TYPE = "Repository" 117 QR_CATEGORY = CATEGORY_QR_REPOSITORY 118 119 def __init__(self, pdata, dbstate, uistate, nav_group=0): 120 121 signal_map = { 122 'repository-add' : self.row_add, 123 'repository-update' : self.row_update, 124 'repository-delete' : self.row_delete, 125 'repository-rebuild' : self.object_build, 126 } 127 128 ListView.__init__( 129 self, _('Repositories'), pdata, dbstate, uistate, 130 RepositoryModel, signal_map, 131 RepoBookmarks, nav_group, 132 multiple=True, 133 filter_class=RepoSidebarFilter) 134 135 self.additional_uis.append(self.additional_ui) 136 137 def navigation_type(self): 138 return 'Repository' 139 140 def drag_info(self): 141 return DdTargets.REPO_LINK 142 143 def get_stock(self): 144 return 'gramps-repository' 145 146 additional_ui = [ # Defines the UI string for UIManager 147 ''' 148 <placeholder id="LocalExport"> 149 <item> 150 <attribute name="action">win.ExportTab</attribute> 151 <attribute name="label" translatable="yes">Export View...</attribute> 152 </item> 153 </placeholder> 154''', 155 ''' 156 <section id="AddEditBook"> 157 <item> 158 <attribute name="action">win.AddBook</attribute> 159 <attribute name="label" translatable="yes">_Add Bookmark</attribute> 160 </item> 161 <item> 162 <attribute name="action">win.EditBook</attribute> 163 <attribute name="label" translatable="no">%s...</attribute> 164 </item> 165 </section> 166''' % _('Organize Bookmarks'), 167 ''' 168 <placeholder id="CommonGo"> 169 <section> 170 <item> 171 <attribute name="action">win.Back</attribute> 172 <attribute name="label" translatable="yes">_Back</attribute> 173 </item> 174 <item> 175 <attribute name="action">win.Forward</attribute> 176 <attribute name="label" translatable="yes">_Forward</attribute> 177 </item> 178 </section> 179 </placeholder> 180''', 181 ''' 182 <section id='CommonEdit' groups='RW'> 183 <item> 184 <attribute name="action">win.Add</attribute> 185 <attribute name="label" translatable="yes">_Add...</attribute> 186 </item> 187 <item> 188 <attribute name="action">win.Edit</attribute> 189 <attribute name="label">%s</attribute> 190 </item> 191 <item> 192 <attribute name="action">win.Remove</attribute> 193 <attribute name="label" translatable="yes">_Delete</attribute> 194 </item> 195 <item> 196 <attribute name="action">win.Merge</attribute> 197 <attribute name="label" translatable="yes">_Merge...</attribute> 198 </item> 199 </section> 200''' % _("action|_Edit..."), # to use sgettext() 201 ''' 202 <placeholder id='otheredit'> 203 <item> 204 <attribute name="action">win.FilterEdit</attribute> 205 <attribute name="label" translatable="yes">''' 206 '''Repository Filter Editor</attribute> 207 </item> 208 </placeholder> 209''', # Following are the Toolbar items 210 ''' 211 <placeholder id='CommonNavigation'> 212 <child groups='RO'> 213 <object class="GtkToolButton"> 214 <property name="icon-name">go-previous</property> 215 <property name="action-name">win.Back</property> 216 <property name="tooltip_text" translatable="yes">''' 217 '''Go to the previous object in the history</property> 218 <property name="label" translatable="yes">_Back</property> 219 <property name="use-underline">True</property> 220 </object> 221 <packing> 222 <property name="homogeneous">False</property> 223 </packing> 224 </child> 225 <child groups='RO'> 226 <object class="GtkToolButton"> 227 <property name="icon-name">go-next</property> 228 <property name="action-name">win.Forward</property> 229 <property name="tooltip_text" translatable="yes">''' 230 '''Go to the next object in the history</property> 231 <property name="label" translatable="yes">_Forward</property> 232 <property name="use-underline">True</property> 233 </object> 234 <packing> 235 <property name="homogeneous">False</property> 236 </packing> 237 </child> 238 </placeholder> 239''', 240 ''' 241 <placeholder id='BarCommonEdit'> 242 <child groups='RW'> 243 <object class="GtkToolButton"> 244 <property name="icon-name">list-add</property> 245 <property name="action-name">win.Add</property> 246 <property name="tooltip_text">%s</property> 247 <property name="label" translatable="yes">_Add...</property> 248 <property name="use-underline">True</property> 249 </object> 250 <packing> 251 <property name="homogeneous">False</property> 252 </packing> 253 </child> 254 <child groups='RW'> 255 <object class="GtkToolButton"> 256 <property name="icon-name">gtk-edit</property> 257 <property name="action-name">win.Edit</property> 258 <property name="tooltip_text">%s</property> 259 <property name="label" translatable="yes">Edit...</property> 260 <property name="use-underline">True</property> 261 </object> 262 <packing> 263 <property name="homogeneous">False</property> 264 </packing> 265 </child> 266 <child groups='RW'> 267 <object class="GtkToolButton"> 268 <property name="icon-name">list-remove</property> 269 <property name="action-name">win.Remove</property> 270 <property name="tooltip_text">%s</property> 271 <property name="label" translatable="yes">_Delete</property> 272 <property name="use-underline">True</property> 273 </object> 274 <packing> 275 <property name="homogeneous">False</property> 276 </packing> 277 </child> 278 <child groups='RW'> 279 <object class="GtkToolButton"> 280 <property name="icon-name">gramps-merge</property> 281 <property name="action-name">win.Merge</property> 282 <property name="tooltip_text">%s</property> 283 <property name="label" translatable="yes">_Merge...</property> 284 <property name="use-underline">True</property> 285 </object> 286 <packing> 287 <property name="homogeneous">False</property> 288 </packing> 289 </child> 290 </placeholder> 291''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG), 292 ''' 293 <menu id="Popup"> 294 <section> 295 <item> 296 <attribute name="action">win.Back</attribute> 297 <attribute name="label" translatable="yes">_Back</attribute> 298 </item> 299 <item> 300 <attribute name="action">win.Forward</attribute> 301 <attribute name="label" translatable="yes">Forward</attribute> 302 </item> 303 </section> 304 <section id="PopUpTree"> 305 </section> 306 <section> 307 <item> 308 <attribute name="action">win.Add</attribute> 309 <attribute name="label" translatable="yes">_Add...</attribute> 310 </item> 311 <item> 312 <attribute name="action">win.Edit</attribute> 313 <attribute name="label">%s</attribute> 314 </item> 315 <item> 316 <attribute name="action">win.Remove</attribute> 317 <attribute name="label" translatable="yes">_Delete</attribute> 318 </item> 319 <item> 320 <attribute name="action">win.Merge</attribute> 321 <attribute name="label" translatable="yes">_Merge...</attribute> 322 </item> 323 </section> 324 <section> 325 <placeholder id='QuickReport'> 326 </placeholder> 327 </section> 328 </menu> 329 ''' % _('action|_Edit...') # to use sgettext() 330 ] 331 332 def add(self, *obj): 333 EditRepository(self.dbstate, self.uistate, [], Repository()) 334 335 def remove(self, *obj): 336 self.remove_selected_objects() 337 338 def remove_object_from_handle(self, handle): 339 source_list = [ 340 item[1] for item in 341 self.dbstate.db.find_backlink_handles(handle, ['Source'])] 342 object = self.dbstate.db.get_repository_from_handle(handle) 343 query = DeleteRepositoryQuery(self.dbstate, self.uistate, object, 344 source_list) 345 is_used = len(source_list) > 0 346 return (query, is_used, object) 347 348 def edit(self, *obj): 349 for handle in self.selected_handles(): 350 repos = self.dbstate.db.get_repository_from_handle(handle) 351 try: 352 EditRepository(self.dbstate, self.uistate, [], repos) 353 except WindowActiveError: 354 pass 355 356 def merge(self, *obj): 357 """ 358 Merge the selected repositories. 359 """ 360 mlist = self.selected_handles() 361 362 if len(mlist) != 2: 363 msg = _("Cannot merge repositories.") 364 msg2 = _("Exactly two repositories must be selected to perform a " 365 "merge. A second repository can be selected by holding " 366 "down the control key while clicking on the desired " 367 "repository.") 368 ErrorDialog(msg, msg2, parent=self.uistate.window) 369 else: 370 MergeRepository(self.dbstate, self.uistate, [], mlist[0], mlist[1]) 371 372 def get_handle_from_gramps_id(self, gid): 373 obj = self.dbstate.db.get_repository_from_gramps_id(gid) 374 if obj: 375 return obj.get_handle() 376 else: 377 return None 378 379 def tag_updated(self, handle_list): 380 """ 381 Update tagged rows when a tag color changes. 382 """ 383 all_links = set([]) 384 for tag_handle in handle_list: 385 links = set([link[1] for link in 386 self.dbstate.db.find_backlink_handles(tag_handle, 387 include_classes='Repository')]) 388 all_links = all_links.union(links) 389 self.row_update(list(all_links)) 390 391 def add_tag(self, transaction, repo_handle, tag_handle): 392 """ 393 Add the given tag to the given repository. 394 """ 395 repo = self.dbstate.db.get_repository_from_handle(repo_handle) 396 repo.add_tag(tag_handle) 397 self.dbstate.db.commit_repository(repo, transaction) 398 399 def get_default_gramplets(self): 400 """ 401 Define the default gramplets for the sidebar and bottombar. 402 """ 403 return (("Repository Filter",), 404 ("Repository Details", 405 "Repository Notes", 406 "Repository Backlinks")) 407