2007-07-11 Don Allingham <don@gramps-project.org>

* src/DbManager.py (DbManager.__button_press): check for node == None



svn: r8713
This commit is contained in:
Don Allingham 2007-07-12 04:24:44 +00:00
parent 5984415471
commit 576c4b705f
5 changed files with 292 additions and 261 deletions

View File

@ -1,3 +1,6 @@
2007-07-11 Don Allingham <don@gramps-project.org>
* src/DbManager.py (DbManager.__button_press): check for node == None
2007-07-10 Alex Roitman <shura@gramps-project.org> 2007-07-10 Alex Roitman <shura@gramps-project.org>
* src/GrampsDb/_GrampsDbWriteXML.py (write_date): Write datespan. * src/GrampsDb/_GrampsDbWriteXML.py (write_date): Write datespan.
* src/GrampsDbUtils/_ReadXML.py: (start_compound_date): Add new * src/GrampsDbUtils/_ReadXML.py: (start_compound_date): Add new

View File

@ -70,6 +70,7 @@ import GrampsDb
import GrampsDbUtils import GrampsDbUtils
import Config import Config
import Mime import Mime
from DdTargets import DdTargets
IMPORT_TYPES = (const.app_gramps_xml, const.app_gedcom, IMPORT_TYPES = (const.app_gramps_xml, const.app_gedcom,
const.app_gramps_package, const.app_geneweb, const.app_gramps_package, const.app_geneweb,
@ -144,22 +145,20 @@ class DbManager:
""" """
Connects the signals to the buttons on the interface. Connects the signals to the buttons on the interface.
""" """
ddtargets = [ DdTargets.URI_LIST.target() ]
self.top.drag_dest_set(gtk.DEST_DEFAULT_ALL, ddtargets, ACTION_COPY)
self.remove.connect('clicked', self.__remove_db) self.remove.connect('clicked', self.__remove_db)
self.new.connect('clicked', self.__new_db) self.new.connect('clicked', self.__new_db)
self.rename.connect('clicked', self.__rename_db) self.rename.connect('clicked', self.__rename_db)
self.repair.connect('clicked', self.__repair_db) self.repair.connect('clicked', self.__repair_db)
if RCS_FOUND:
self.rcs.connect('clicked', self.__rcs)
self.selection.connect('changed', self.__selection_changed) self.selection.connect('changed', self.__selection_changed)
self.dblist.connect('button-press-event', self.__button_press) self.dblist.connect('button-press-event', self.__button_press)
self.top.drag_dest_set(
gtk.DEST_DEFAULT_ALL,
(('text/plain', 0, 1),
('text/uri-list', 0, 2)),
ACTION_COPY)
self.top.connect('drag_data_received', self.__drag_data_received) self.top.connect('drag_data_received', self.__drag_data_received)
if RCS_FOUND:
self.rcs.connect('clicked', self.__rcs)
def __button_press(self, obj, event): def __button_press(self, obj, event):
""" """
Checks for a double click event. In the tree view, we want to Checks for a double click event. In the tree view, we want to
@ -168,6 +167,8 @@ class DbManager:
""" """
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
store, node = self.selection.get_selected() store, node = self.selection.get_selected()
if not node:
return
# don't open a locked file # don't open a locked file
if store.get_value(node, STOCK_COL) == 'gramps-lock': if store.get_value(node, STOCK_COL) == 'gramps-lock':
self.__ask_to_break_lock(store, node) self.__ask_to_break_lock(store, node)
@ -658,6 +659,7 @@ class DbManager:
# Check for Thunar # Check for Thunar
uris = selection.get_uris() uris = selection.get_uris()
if uris: # Thunar if uris: # Thunar
drag_value = uris[0] drag_value = uris[0]
elif selection.get_text(): # Nautilus elif selection.get_text(): # Nautilus

View File

@ -60,7 +60,7 @@ class _DdType:
_APP_ID_OFFSET = 40 # Starting value of app_ids _APP_ID_OFFSET = 40 # Starting value of app_ids
def __init__(self,container,drag_type,target_flags=0,app_id=None): def __init__(self, container, drag_type, target_flags=0, app_id=None):
"""Create a new DdType: """Create a new DdType:
drag_type: string holding the name of the type. drag_type: string holding the name of the type.
@ -83,7 +83,7 @@ class _DdType:
def target(self): def target(self):
"""return the full target information in the format """return the full target information in the format
required by the Gtk functions.""" required by the Gtk functions."""
return (self.drag_type,self.target_flags,self.app_id) return (self.drag_type, self.target_flags, self.app_id)
@ -106,30 +106,30 @@ class _DdTargets(object):
self._type_map = {} self._type_map = {}
self._app_id_map = {} self._app_id_map = {}
self.URL = _DdType(self,'url') self.URL = _DdType(self, 'url')
self.EVENT = _DdType(self,'pevent') self.EVENT = _DdType(self, 'pevent')
self.EVENTREF = _DdType(self,'eventref') self.EVENTREF = _DdType(self, 'eventref')
self.ATTRIBUTE = _DdType(self,'pattr') self.ATTRIBUTE = _DdType(self, 'pattr')
self.ADDRESS = _DdType(self,'paddr') self.ADDRESS = _DdType(self, 'paddr')
self.LOCATION = _DdType(self,'location') self.LOCATION = _DdType(self, 'location')
self.SOURCEREF = _DdType(self,'srcref') self.SOURCEREF = _DdType(self, 'srcref')
self.REPOREF = _DdType(self,'reporef') self.REPOREF = _DdType(self, 'reporef')
self.REPO_LINK = _DdType(self,'repo-link') self.REPO_LINK = _DdType(self, 'repo-link')
self.PLACE_LINK= _DdType(self,'place-link') self.PLACE_LINK = _DdType(self, 'place-link')
self.NAME = _DdType(self,'name') self.NAME = _DdType(self, 'name')
self.MEDIAOBJ = _DdType(self,'mediaobj') self.MEDIAOBJ = _DdType(self, 'mediaobj')
self.MEDIAREF = _DdType(self,'mediaref') self.MEDIAREF = _DdType(self, 'mediaref')
self.DATA = _DdType(self,'data_tuple') self.DATA = _DdType(self, 'data_tuple')
self.NOTE_LINK = _DdType(self,'note-link') self.NOTE_LINK = _DdType(self, 'note-link')
self.PERSON_LINK = _DdType(self,'person-link') self.PERSON_LINK = _DdType(self, 'person-link')
self.PERSON_LINK_LIST = _DdType(self,'person-link-list') self.PERSON_LINK_LIST = _DdType(self, 'person-link-list')
self.PERSONREF = _DdType(self,'personref') self.PERSONREF = _DdType(self, 'personref')
self.SOURCE_LINK = _DdType(self,'source-link') self.SOURCE_LINK = _DdType(self, 'source-link')
self.FAMILY_EVENT = _DdType(self,'fevent') self.FAMILY_EVENT = _DdType(self, 'fevent')
self.FAMILY_ATTRIBUTE = _DdType(self,'fattr') self.FAMILY_ATTRIBUTE = _DdType(self, 'fattr')
# List of all types that are used between # List of all types that are used between
# gramps widgets but should not be exported # gramps widgets but should not be exported
@ -155,15 +155,15 @@ class _DdTargets(object):
self.NOTE_LINK, self.NOTE_LINK,
] ]
self.CHILD = _DdType(self,'child') self.CHILD = _DdType(self, 'child')
self.SPOUSE = _DdType(self,'spouse') self.SPOUSE = _DdType(self, 'spouse')
self.TEXT = _DdType(self,'TEXT',0,1) self.TEXT = _DdType(self, 'TEXT', 0, 1)
self.TEXT_MIME = _DdType(self,'text/plain',0,0) self.TEXT_MIME = _DdType(self, 'text/plain', 0, 0)
self.STRING = _DdType(self,'STRING', 0, 2) self.STRING = _DdType(self, 'STRING', 0, 2)
self.COMPOUND_TEXT = _DdType(self,'COMPOUND_TEXT', 0, 3) self.COMPOUND_TEXT = _DdType(self, 'COMPOUND_TEXT', 0, 3)
self.UTF8_STRING = _DdType(self,'UTF8_STRING', 0, 4) self.UTF8_STRING = _DdType(self, 'UTF8_STRING', 0, 4)
self.URI_LIST = _DdType(self,'text/uri-list', 0, 5) self.URI_LIST = _DdType(self, 'text/uri-list', 0, 5)
self.APP_ROOT = _DdType(self,'application/x-rootwin-drop', 0, 6) self.APP_ROOT = _DdType(self, 'application/x-rootwin-drop', 0, 6)
# List of all the test types. These are types # List of all the test types. These are types
# that can be interpreted as text. # that can be interpreted as text.
@ -173,20 +173,20 @@ class _DdTargets(object):
self.STRING, self.STRING,
self.COMPOUND_TEXT) self.COMPOUND_TEXT)
def insert(self,dd_type): def insert(self, dd_type):
"""Add a target to the lookup lists. These lists are """Add a target to the lookup lists. These lists are
used purely for performance reasons.""" used purely for performance reasons."""
self._type_map[dd_type.drag_type] = dd_type self._type_map[dd_type.drag_type] = dd_type
self._app_id_map[dd_type.app_id] = dd_type self._app_id_map[dd_type.app_id] = dd_type
def get_dd_type_from_type_name(self,type_name): def get_dd_type_from_type_name(self, type_name):
return self._type_map.get(type_name,None) return self._type_map.get(type_name, None)
def get_dd_type_from_app_id(self,app_id): def get_dd_type_from_app_id(self, app_id):
return self._app_id_map.get(app_id,None) return self._app_id_map.get(app_id, None)
def is_text_type(self,type_name): def is_text_type(self, type_name):
return type_name in self.all_text_types() return type_name in self.all_text_types()
def all_text(self): def all_text(self):
@ -198,7 +198,7 @@ class _DdTargets(object):
return tuple([t.drag_type for t in self._all_text_types]) return tuple([t.drag_type for t in self._all_text_types])
def is_gramps_type(self,type_name): def is_gramps_type(self, type_name):
return type_name in self.all_gramps_types() return type_name in self.all_gramps_types()
def all_gramps_types(self): def all_gramps_types(self):

View File

@ -85,7 +85,7 @@ def get_researcher():
e = Config.get(Config.RESEARCHER_EMAIL) e = Config.get(Config.RESEARCHER_EMAIL)
owner = RelLib.Researcher() owner = RelLib.Researcher()
owner.set(n,a,c,s,ct,p,ph,e) owner.set(n, a, c, s, ct, p, ph, e)
return owner return owner
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -96,14 +96,14 @@ def get_researcher():
class GrampsPreferences(ManagedWindow.ManagedWindow): class GrampsPreferences(ManagedWindow.ManagedWindow):
def __init__(self, uistate, dbstate): def __init__(self, uistate, dbstate):
ManagedWindow.ManagedWindow.__init__(self,uistate,[],GrampsPreferences) ManagedWindow.ManagedWindow.__init__(self, uistate, [], GrampsPreferences)
self.dbstate = dbstate self.dbstate = dbstate
self.set_window( self.set_window(
gtk.Dialog(_('Preferences'), gtk.Dialog(_('Preferences'),
flags=gtk.DIALOG_NO_SEPARATOR, flags=gtk.DIALOG_NO_SEPARATOR,
buttons=(gtk.STOCK_CLOSE,gtk.RESPONSE_CLOSE)), buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
None, _('Preferences'), None) None, _('Preferences'), None)
panel = gtk.Notebook() panel = gtk.Notebook()
@ -111,7 +111,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.original = Config.get(Config.TRANSACTIONS) self.original = Config.get(Config.TRANSACTIONS)
self.window.vbox.add(panel) self.window.vbox.add(panel)
self.window.connect('response',self.done) self.window.connect('response', self.done)
panel.append_page(self.add_behavior_panel(), panel.append_page(self.add_behavior_panel(),
MarkupLabel(_('General'))) MarkupLabel(_('General')))
panel.append_page(self.add_database_panel(), panel.append_page(self.add_database_panel(),
@ -138,7 +138,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.close() self.close()
def add_researcher_panel(self): def add_researcher_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -153,7 +153,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table return table
def add_prefix_panel(self): def add_prefix_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -167,7 +167,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table return table
def add_advanced_panel(self): def add_advanced_panel(self):
table = gtk.Table(4,8) table = gtk.Table(4, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -191,7 +191,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table return table
def add_color_panel(self): def add_color_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(12) table.set_col_spacings(12)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -210,9 +210,9 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def reset_colors(self, obj): def reset_colors(self, obj):
def_comp = Config.get_default(Config.COMPLETE_COLOR,'') def_comp = Config.get_default(Config.COMPLETE_COLOR, '')
def_todo = Config.get_default(Config.TODO_COLOR,'') def_todo = Config.get_default(Config.TODO_COLOR, '')
def_cust = Config.get_default(Config.CUSTOM_MARKER_COLOR,'') def_cust = Config.get_default(Config.CUSTOM_MARKER_COLOR, '')
Config.set(Config.COMPLETE_COLOR, def_comp) Config.set(Config.COMPLETE_COLOR, def_comp)
Config.set(Config.TODO_COLOR, def_todo) Config.set(Config.TODO_COLOR, def_todo)
@ -221,7 +221,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.comp_color.set_color(gtk.gdk.color_parse(def_comp)) self.comp_color.set_color(gtk.gdk.color_parse(def_comp))
self.todo_color.set_color(gtk.gdk.color_parse(def_todo)) self.todo_color.set_color(gtk.gdk.color_parse(def_todo))
self.custom_color.set_color(gtk.gdk.color_parse(def_cust)) self.custom_color.set_color(gtk.gdk.color_parse(def_cust))
for widget in [self.comp_color,self.todo_color,self.custom_color]: for widget in [self.comp_color, self.todo_color, self.custom_color]:
widget.emit('color-set') widget.emit('color-set')
def add_name_panel(self): def add_name_panel(self):
@ -239,14 +239,14 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.examplename.set_patronymic('Patronymic') self.examplename.set_patronymic('Patronymic')
self.examplename.set_call_name('Ed') self.examplename.set_call_name('Ed')
table = gtk.Table(2,2) table = gtk.Table(2, 2)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
# get the model for the combo and the treeview # get the model for the combo and the treeview
active = _nd.get_default_format() active = _nd.get_default_format()
self.fmt_model,active = self._build_name_format_model(active) self.fmt_model, active = self._build_name_format_model(active)
# set up the combo to choose the preset format # set up the combo to choose the preset format
self.fmt_obox = gtk.ComboBox() self.fmt_obox = gtk.ComboBox()
@ -276,30 +276,30 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table return table
def _build_name_format_model(self,active): def _build_name_format_model(self, active):
""" """
Create a common model for ComboBox and TreeView Create a common model for ComboBox and TreeView
""" """
name_format_model = gtk.ListStore(int,str,str,str) name_format_model = gtk.ListStore(int, str, str, str)
index = 0 index = 0
the_index = 0 the_index = 0
for num,name,fmt_str,act in _nd.get_name_format(): for num, name, fmt_str, act in _nd.get_name_format():
self.examplename.set_display_as(num) self.examplename.set_display_as(num)
name_format_model.append( name_format_model.append(
row=[num, name, fmt_str, _nd.display_name(self.examplename)]) row=[num, name, fmt_str, _nd.display_name(self.examplename)])
if num == active: the_index = index if num == active: the_index = index
index += 1 index += 1
return name_format_model,the_index return name_format_model, the_index
def _build_custom_name_ui(self): def _build_custom_name_ui(self):
""" """
UI to manage the custom name formats UI to manage the custom name formats
""" """
table = gtk.Table(2,3) table = gtk.Table(2, 3)
table.set_border_width(6) table.set_border_width(6)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -322,7 +322,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
# ... and put it into a scrolled win # ... and put it into a scrolled win
format_sw = gtk.ScrolledWindow() format_sw = gtk.ScrolledWindow()
format_sw.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) format_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
format_sw.add(format_tree) format_sw.add(format_tree)
format_sw.set_shadow_type(gtk.SHADOW_IN) format_sw.set_shadow_type(gtk.SHADOW_IN)
table.attach(format_sw, 0, 3, 0, 1, yoptions=gtk.FILL|gtk.EXPAND) table.attach(format_sw, 0, 3, 0, 1, yoptions=gtk.FILL|gtk.EXPAND)
@ -332,30 +332,30 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.iter = None self.iter = None
insert_button = gtk.Button(stock=gtk.STOCK_ADD) insert_button = gtk.Button(stock=gtk.STOCK_ADD)
insert_button.connect('clicked',self.cb_insert_fmt_str) insert_button.connect('clicked', self.cb_insert_fmt_str)
self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT) self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT)
self.edit_button.connect('clicked',self.cb_edit_fmt_str) self.edit_button.connect('clicked', self.cb_edit_fmt_str)
self.edit_button.set_sensitive(False) self.edit_button.set_sensitive(False)
self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE) self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
self.remove_button.connect('clicked',self.cb_del_fmt_str) self.remove_button.connect('clicked', self.cb_del_fmt_str)
self.remove_button.set_sensitive(False) self.remove_button.set_sensitive(False)
table.attach(insert_button, 0, 1, 1, 2,yoptions=0) table.attach(insert_button, 0, 1, 1, 2, yoptions=0)
table.attach(self.remove_button, 1, 2, 1, 2,yoptions=0) table.attach(self.remove_button, 1, 2, 1, 2, yoptions=0)
table.attach(self.edit_button, 2, 3, 1, 2,yoptions=0) table.attach(self.edit_button, 2, 3, 1, 2, yoptions=0)
return table return table
def cb_name_changed(self,obj): def cb_name_changed(self, obj):
""" """
Preset name format ComboBox callback Preset name format ComboBox callback
""" """
the_list = obj.get_model() the_list = obj.get_model()
the_iter = obj.get_active_iter() the_iter = obj.get_active_iter()
new_idx = the_list.get_value(the_iter,COL_NUM) new_idx = the_list.get_value(the_iter, COL_NUM)
Config.set(Config.NAME_FORMAT,new_idx) Config.set(Config.NAME_FORMAT, new_idx)
_nd.set_default_format(new_idx) _nd.set_default_format(new_idx)
self.uistate.emit('nameformat-changed') self.uistate.emit('nameformat-changed')
@ -367,53 +367,53 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
and set the Remove and Edit button sensitivity and set the Remove and Edit button sensitivity
""" """
model,self.iter = tree_selection.get_selected() model, self.iter = tree_selection.get_selected()
if self.iter == None: if self.iter == None:
tree_selection.select_path(0) tree_selection.select_path(0)
model,self.iter = tree_selection.get_selected() model, self.iter = tree_selection.get_selected()
self.selected_fmt = model.get(self.iter, 0, 1, 2) self.selected_fmt = model.get(self.iter, 0, 1, 2)
idx = self.selected_fmt[COL_NUM] < 0 idx = self.selected_fmt[COL_NUM] < 0
self.remove_button.set_sensitive(idx) self.remove_button.set_sensitive(idx)
self.edit_button.set_sensitive(idx) self.edit_button.set_sensitive(idx)
def cb_edit_fmt_str(self,obj): def cb_edit_fmt_str(self, obj):
""" """
Name format editor Edit button callback Name format editor Edit button callback
""" """
num,name,fmt = self.selected_fmt[COL_NUM:COL_EXPL] num, name, fmt = self.selected_fmt[COL_NUM:COL_EXPL]
dlg = NameFormatEditDlg(name, fmt, self.examplename) dlg = NameFormatEditDlg(name, fmt, self.examplename)
dlg.dlg.set_transient_for(self.window) dlg.dlg.set_transient_for(self.window)
(res,name,fmt) = dlg.run() (res, name, fmt) = dlg.run()
if res == gtk.RESPONSE_OK and (name != self.selected_fmt[COL_NAME] or if res == gtk.RESPONSE_OK and (name != self.selected_fmt[COL_NAME] or
fmt != self.selected_fmt[COL_FMT]): fmt != self.selected_fmt[COL_FMT]):
exmpl = _nd.format_str(self.examplename,fmt) exmpl = _nd.format_str(self.examplename, fmt)
self.fmt_model.set(self.iter,COL_NAME,name, self.fmt_model.set(self.iter, COL_NAME, name,
COL_FMT,fmt, COL_FMT, fmt,
COL_EXPL,exmpl) COL_EXPL, exmpl)
self.selected_fmt = (num,name,fmt,exmpl) self.selected_fmt = (num, name, fmt, exmpl)
_nd.edit_name_format(num,name,fmt) _nd.edit_name_format(num, name, fmt)
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True, self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False) only_active=False)
def cb_insert_fmt_str(self,obj): def cb_insert_fmt_str(self, obj):
""" """
Name format editor Insert button callback Name format editor Insert button callback
""" """
dlg = NameFormatEditDlg('','',self.examplename) dlg = NameFormatEditDlg('', '', self.examplename)
dlg.dlg.set_transient_for(self.window) dlg.dlg.set_transient_for(self.window)
(res,n,f) = dlg.run() (res, n, f) = dlg.run()
if res == gtk.RESPONSE_OK: if res == gtk.RESPONSE_OK:
i = _nd.add_name_format(n,f) i = _nd.add_name_format(n, f)
self.fmt_model.append(row=[i,n,f, self.fmt_model.append(row=[i, n, f,
_nd.format_str(self.examplename,f)]) _nd.format_str(self.examplename, f)])
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True, self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False) only_active=False)
def cb_del_fmt_str(self,obj): def cb_del_fmt_str(self, obj):
""" """
Name format editor Remove button callback Name format editor Remove button callback
""" """
@ -428,7 +428,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
only_active=False) only_active=False)
def add_formats_panel(self): def add_formats_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -494,7 +494,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
'effect until the next time GRAMPS is started.')) 'effect until the next time GRAMPS is started.'))
def add_behavior_panel(self): def add_behavior_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -515,7 +515,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table return table
def add_database_panel(self): def add_database_panel(self):
table = gtk.Table(3,8) table = gtk.Table(3, 8)
table.set_border_width(12) table.set_border_width(12)
table.set_col_spacings(6) table.set_col_spacings(6)
table.set_row_spacings(6) table.set_row_spacings(6)
@ -532,7 +532,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def add_checkbox(self, table, label, index, constant): def add_checkbox(self, table, label, index, constant):
checkbox = gtk.CheckButton(label) checkbox = gtk.CheckButton(label)
checkbox.set_active(Config.get(constant)) checkbox.set_active(Config.get(constant))
checkbox.connect('toggled',self.update_checkbox, constant) checkbox.connect('toggled', self.update_checkbox, constant)
table.attach(checkbox, 1, 3, index, index+1, yoptions=0) table.attach(checkbox, 1, 3, index, index+1, yoptions=0)
def add_entry(self, table, label, index, constant): def add_entry(self, table, label, index, constant):
@ -550,7 +550,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
color = gtk.gdk.color_parse(hexval) color = gtk.gdk.color_parse(hexval)
entry = gtk.ColorButton(color=color) entry = gtk.ColorButton(color=color)
color_hex_label = BasicLabel(hexval) color_hex_label = BasicLabel(hexval)
entry.connect('color-set',self.update_color,constant,color_hex_label) entry.connect('color-set', self.update_color, constant, color_hex_label)
table.attach(lwidget, 0, 1, index, index+1, yoptions=0, table.attach(lwidget, 0, 1, index, index+1, yoptions=0,
xoptions=gtk.FILL) xoptions=gtk.FILL)
table.attach(entry, 1, 2, index, index+1, yoptions=0, xoptions=0) table.attach(entry, 1, 2, index, index+1, yoptions=0, xoptions=0)
@ -571,8 +571,8 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def update_checkbox(self, obj, constant): def update_checkbox(self, obj, constant):
Config.set(constant, obj.get_active()) Config.set(constant, obj.get_active())
def build_menu_names(self,obj): def build_menu_names(self, obj):
return (_('Preferences'),None) return (_('Preferences'), None)
# FIXME: is this needed? # FIXME: is this needed?
def _set_button(stock): def _set_button(stock):
@ -594,7 +594,7 @@ class NameFormatEditDlg:
self.name = name self.name = name
self.valid = True self.valid = True
self.top = gtk.glade.XML(const.gladeFile, 'namefmt_edit','gramps') self.top = gtk.glade.XML(const.gladeFile, 'namefmt_edit', 'gramps')
self.dlg = self.top.get_widget('namefmt_edit') self.dlg = self.top.get_widget('namefmt_edit')
ManagedWindow.set_titles(self.dlg, None, _('Name Format Editor')) ManagedWindow.set_titles(self.dlg, None, _('Name Format Editor'))

View File

@ -18,6 +18,10 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
"""
Provides the basic functionality for a list view
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# GTK # GTK
@ -26,7 +30,6 @@
import gtk import gtk
import pango import pango
import const import const
gtk26 = gtk.pygtk_version >= (2,6,0)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -48,19 +51,22 @@ NOSORT = -1
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class ListModel: class ListModel:
def __init__(self,tree,dlist,select_func=None, def __init__(self, tree, dlist, select_func=None, event_func=None,
event_func=None,mode=gtk.SELECTION_SINGLE): mode=gtk.SELECTION_SINGLE):
self.tree = tree self.tree = tree
self.tree.set_fixed_height_mode(True) self.tree.set_fixed_height_mode(True)
self.mylist = [] self.mylist = []
self.data_index = 0 self.data_index = 0
for l in dlist: self.sel_iter = None
if len(l)>3:
if l[3] == TOGGLE: for info in dlist:
if len(info) > 3:
if info[3] == TOGGLE:
self.mylist.append(bool) self.mylist.append(bool)
elif l[3] == IMAGE: elif info[3] == IMAGE:
self.mylist.append(gtk.gdk.Pixbuf) self.mylist.append(gtk.gdk.Pixbuf)
elif l[3] == INTEGER: elif info[3] == INTEGER:
self.mylist.append(int) self.mylist.append(int)
else: else:
self.mylist.append(str) self.mylist.append(str)
@ -78,50 +84,48 @@ class ListModel:
self.cids = [] self.cids = []
self.idmap = {} self.idmap = {}
self.__build_columns(dlist)
self.__connect_model()
if select_func:
self.selection.connect('changed', select_func)
if event_func:
self.double_click = event_func
self.tree.connect('event', self.__button_press)
def __build_columns(self, dlist):
"""
Builds the columns based of the data in dlist
"""
cnum = 0 cnum = 0
for name in dlist:
if not name[2]: for name in [ item for item in dlist if item[2]]:
continue
if len(name) == 3: if len(name) == 3:
name = (name[0],name[1],name[2],TEXT,False, None) name = (name[0], name[1], name[2], TEXT, False, None)
elif len(name) == 4: elif len(name) == 4:
name = (name[0],name[1],name[2],name[3],False, None) name = (name[0], name[1], name[2], name[3], False, None)
if name[0] and name[3] == TOGGLE: if name[0] and name[3] == TOGGLE:
renderer = gtk.CellRendererToggle() renderer = gtk.CellRendererToggle()
column = gtk.TreeViewColumn(name[0],renderer) column = gtk.TreeViewColumn(name[0], renderer)
column.add_attribute(renderer,'active',cnum) column.add_attribute(renderer, 'active', cnum)
elif name[0] and name[3] == IMAGE: elif name[0] and name[3] == IMAGE:
renderer = gtk.CellRendererPixbuf() renderer = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn(name[0],renderer) column = gtk.TreeViewColumn(name[0], renderer)
column.add_attribute(renderer,'pixbuf',cnum) column.add_attribute(renderer, 'pixbuf', cnum)
renderer.set_property('height',const.thumbScale/2) renderer.set_property('height', const.thumbScale/2)
elif gtk26 and name[3] == COMBO:
store = gtk.ListStore(str)
model = gtk.ListStore(str, object)
for val in name[4]:
model.append((val,store))
self.function[cnum] = name[5]
renderer = gtk.CellRendererCombo()
renderer.set_property('model',model)
renderer.set_property('text_column',0)
renderer.set_fixed_height_from_font(True)
renderer.set_property('editable',True)
renderer.connect('edited',self.edited_cb, cnum)
column = gtk.TreeViewColumn(name[0],renderer,text=cnum)
column.set_reorderable(True)
else: else:
renderer = gtk.CellRendererText() renderer = gtk.CellRendererText()
renderer.set_fixed_height_from_font(True) renderer.set_fixed_height_from_font(True)
renderer.set_property('ellipsize', pango.ELLIPSIZE_END) renderer.set_property('ellipsize', pango.ELLIPSIZE_END)
if name[5]: if name[5]:
renderer.set_property('editable',True) renderer.set_property('editable', True)
renderer.connect('edited',self.edited_cb, cnum) renderer.connect('edited', self.__edited_cb, cnum)
self.function[cnum] = name[5] self.function[cnum] = name[5]
else: else:
renderer.set_property('editable',False) renderer.set_property('editable', False)
column = gtk.TreeViewColumn(name[0],renderer,text=cnum) column = gtk.TreeViewColumn(name[0], renderer, text=cnum)
column.set_reorderable(True) column.set_reorderable(True)
column.set_min_width(name[2]) column.set_min_width(name[2])
@ -143,26 +147,30 @@ class ListModel:
if name[0] != '': if name[0] != '':
self.tree.append_column(column) self.tree.append_column(column)
self.connect_model() def __edited_cb(self, cell, path, new_text, col):
"""
if select_func: Callback executed when the text of the cell renderer has changed
self.selection.connect('changed',select_func) """
if event_func:
self.double_click = event_func
self.tree.connect('event',self.button_press)
def edited_cb(self, cell, path, new_text, col):
self.model[path][col] = new_text self.model[path][col] = new_text
if self.function.has_key(col): if self.function.has_key(col):
self.function[col](int(path),new_text) self.function[col](int(path), new_text)
def unselect(self): def unselect(self):
"""
Removes the selection from the view
"""
self.selection.unselect_all() self.selection.unselect_all()
def set_reorderable(self,order): def set_reorderable(self, order):
"""
Enables or disables reordering of data
"""
self.tree.set_reorderable(order) self.tree.set_reorderable(order)
def new_model(self): def new_model(self):
"""
Creates a new model instance
"""
if self.model: if self.model:
self.cid = self.model.get_sort_column_id() self.cid = self.model.get_sort_column_id()
del self.model del self.model
@ -174,7 +182,10 @@ class ListModel:
self.selection.set_mode(self.mode) self.selection.set_mode(self.mode)
self.sel_iter = None self.sel_iter = None
def connect_model(self): def __connect_model(self):
"""
Connects the model to the associated tree
"""
self.tree.set_model(self.model) self.tree.set_model(self.model)
if self.sel_iter: if self.sel_iter:
self.selection.select_iter(self.sel_iter) self.selection.select_iter(self.sel_iter)
@ -184,31 +195,43 @@ class ListModel:
val = self.model.get_sort_column_id() val = self.model.get_sort_column_id()
if val[0] == -2 and self.cid: if val[0] == -2 and self.cid:
self.model.set_sort_column_id(self.cid[0],self.cid[1]) self.model.set_sort_column_id(self.cid[0], self.cid[1])
self.sort() self.sort()
def sort(self): def sort(self):
"""
Sorts the current view
"""
val = self.model.get_sort_column_id() val = self.model.get_sort_column_id()
col = val[0] col = val[0]
if col < 0: if col < 0:
return return
if col > 0: if col > 0:
self.model.set_sort_column_id(col,val[1]) self.model.set_sort_column_id(col, val[1])
else: else:
self.model.set_sort_column_id(self.cids[0],val[1]) self.model.set_sort_column_id(self.cids[0], val[1])
self.model.sort_column_changed() self.model.sort_column_changed()
def get_selected(self): def get_selected(self):
"""
Returns the selected items
"""
return self.selection.get_selected() return self.selection.get_selected()
def get_row_at(self,x,y): def get_row_at(self, xpos, ypos):
path = self.tree.get_path_at_pos(x,y) """
Returns the row at the specified (x,y) coordinates
"""
path = self.tree.get_path_at_pos(xpos, ypos)
if path == None: if path == None:
return self.count -1 return self.count -1
else: else:
return path[0][0]-1 return path[0][0]-1
def get_selected_row(self): def get_selected_row(self):
"""
Gets the selected row number
"""
store, node = self.selection.get_selected() store, node = self.selection.get_selected()
if node: if node:
rows = store.get_path(node) rows = store.get_path(node)
@ -220,75 +243,75 @@ class ListModel:
if self.count == 0: if self.count == 0:
return [] return []
elif self.mode == gtk.SELECTION_SINGLE: elif self.mode == gtk.SELECTION_SINGLE:
store,node = self.selection.get_selected() store, node = self.selection.get_selected()
if node: if node:
return [self.model.get_value(node,self.data_index)] return [self.model.get_value(node, self.data_index)]
else: else:
return [] return []
else: else:
mlist = [] mlist = []
self.selection.selected_foreach(self.blist,mlist) self.selection.selected_foreach(self.blist, mlist)
return mlist return mlist
def get_icon(self): def get_icon(self):
if self.mode == gtk.SELECTION_SINGLE: if self.mode == gtk.SELECTION_SINGLE:
store,node = self.selection.get_selected() store, node = self.selection.get_selected()
path = self.model.get_path(node) path = self.model.get_path(node)
else: else:
mlist = [] mlist = []
self.selection.selected_foreach(self.blist,mlist) self.selection.selected_foreach(self.blist, mlist)
path = self.model.get_path(mlist[0]) path = self.model.get_path(mlist[0])
return self.tree.create_row_drag_icon(path) return self.tree.create_row_drag_icon(path)
def blist(self,store,path,node,list): def blist(self, store, path, node, dlist):
list.append(self.model.get_value(node,self.data_index)) dlist.append(self.model.get_value(node, self.data_index))
def clear(self): def clear(self):
self.count = 0 self.count = 0
self.model.clear() self.model.clear()
def remove(self,node): def remove(self, node):
self.model.remove(node) self.model.remove(node)
self.count -= 1 self.count -= 1
def get_row(self,node): def get_row(self, node):
row = self.model.get_path(node) row = self.model.get_path(node)
return row[0] return row[0]
def select_row(self,row): def select_row(self, row):
self.selection.select_path((row)) self.selection.select_path((row))
def select_iter(self,node): def select_iter(self, node):
self.selection.select_iter(node) self.selection.select_iter(node)
def get_object(self,node): def get_object(self, node):
return self.model.get_value(node,self.data_index) return self.model.get_value(node, self.data_index)
def insert(self,position,data,info=None,select=0): def insert(self, position, data, info=None, select=0):
self.count += 1 self.count += 1
node = self.model.insert(position) node = self.model.insert(position)
col = 0 col = 0
for obj in data: for obj in data:
self.model.set_value(node,col,obj) self.model.set_value(node, col, obj)
col += 1 col += 1
self.model.set_value(node,col,info) self.model.set_value(node, col, info)
if info: if info:
self.idmap[str(info)] = node self.idmap[str(info)] = node
if select: if select:
self.selection.select_iter(node) self.selection.select_iter(node)
return node return node
def get_data(self,node,cols): def get_data(self, node, cols):
return [ self.model.get_value(node,c) for c in cols ] return [ self.model.get_value(node, c) for c in cols ]
def add(self,data,info=None,select=0): def add(self, data, info=None, select=0):
self.count += 1 self.count += 1
node = self.model.append() node = self.model.append()
col = 0 col = 0
for obj in data: for obj in data:
self.model.set_value(node,col,obj) self.model.set_value(node, col, obj)
col += 1 col += 1
self.model.set_value(node,col,info) self.model.set_value(node, col, info)
if info: if info:
self.idmap[str(info)] = node self.idmap[str(info)] = node
if select: if select:
@ -296,43 +319,46 @@ class ListModel:
self.selection.select_iter(self.sel_iter) self.selection.select_iter(self.sel_iter)
return node return node
def set(self,node,data,info=None,select=0): def set(self, node, data, info=None, select=0):
col = 0 col = 0
for obj in data: for obj in data:
self.model.set_value(node,col,obj) self.model.set_value(node, col, obj)
col += 1 col += 1
self.model.set_value(node,col,info) self.model.set_value(node, col, info)
if info: if info:
self.idmap[str(info)] = node self.idmap[str(info)] = node
if select: if select:
self.sel_iter = node self.sel_iter = node
return node return node
def add_and_select(self,data,info=None): def add_and_select(self, data, info=None):
self.count += 1 self.count += 1
node = self.model.append() node = self.model.append()
col = 0 col = 0
for obj in data: for obj in data:
self.model.set_value(node,col,obj) self.model.set_value(node, col, obj)
col += 1 col += 1
if info: if info:
self.idmap[str(info)] = node self.idmap[str(info)] = node
self.model.set_value(node,col,info) self.model.set_value(node, col, info)
self.selection.select_iter(node) self.selection.select_iter(node)
def center_selected(self): def center_selected(self):
model,node = self.selection.get_selected() model, node = self.selection.get_selected()
if node: if node:
path = model.get_path(node) path = model.get_path(node)
self.tree.scroll_to_cell(path,None,True,0.5,0.5) self.tree.scroll_to_cell(path, None, True, 0.5, 0.5)
def button_press(self,obj,event): def __button_press(self, obj, event):
"""
Called when a button press is executed
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
self.double_click(obj) self.double_click(obj)
return True return True
return False return False
def find(self,info): def find(self, info):
if info in self.idmap.keys(): if info in self.idmap.keys():
node = self.idmap[str(info)] node = self.idmap[str(info)]
self.selection.select_iter(node) self.selection.select_iter(node)